Index: trunk/src/org/expeditee/auth/Actions.java
===================================================================
--- trunk/src/org/expeditee/auth/Actions.java	(revision 1362)
+++ trunk/src/org/expeditee/auth/Actions.java	(revision 1363)
@@ -23,5 +23,4 @@
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -39,5 +38,4 @@
 import org.expeditee.agents.ExistingFramesetException;
 import org.expeditee.agents.InvalidFramesetNameException;
-import org.expeditee.auth.Mail.MailEntry;
 import org.expeditee.auth.account.Authenticate;
 import org.expeditee.auth.account.Authenticate.AuthenticationResult;
@@ -45,7 +43,8 @@
 import org.expeditee.auth.account.Create.CreateResult;
 import org.expeditee.auth.account.Password;
-import org.expeditee.auth.gui.MailBay;
+import org.expeditee.auth.mail.Mail;
+import org.expeditee.auth.mail.Mail.MailEntry;
+import org.expeditee.auth.mail.gui.MailBay;
 import org.expeditee.auth.tags.AuthenticationTag;
-import org.expeditee.core.Colour;
 import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.DisplayController;
@@ -56,5 +55,4 @@
 import org.expeditee.items.Text;
 import org.expeditee.settings.UserSettings;
-import org.expeditee.settings.identity.passwordrecovery.Colleagues;
 import org.expeditee.settings.identity.secrets.KeyList;
 import org.expeditee.stats.Formatter;
@@ -63,5 +61,5 @@
 public class Actions implements CryptographyConstants {
 	
-	//Debug Functions
+	//	Start Debug Actions
 	public static void SendTestMessage(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, FileNotFoundException, KeyStoreException, CertificateException, ClassNotFoundException, IOException, SQLException {
 		String time = org.expeditee.stats.Formatter.getDateTime();
@@ -75,4 +73,5 @@
 		MessageBay.displayMessage("Test message sent.");
 	}
+	
 	public static void SendTestMessageHemi(String param) {
 		String time = Formatter.getDateTime();
@@ -87,4 +86,5 @@
 		MessageBay.displayMessage("Test message sent.");
 	}
+	
 	public static void SendTestOneOffMessage(String colleagueName) {
 		String time = Formatter.getDateTime();
@@ -101,25 +101,4 @@
 		Mail.sendOneOffMail(mail, colleagueName, key);
 	}
-	public static void AuthOneOffSecureMessage(Text cursor, Text actionItem) {
-		byte[] keyBytes = Base64.getDecoder().decode(cursor.getText());
-		SecretKey key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
-		List<String> data = actionItem.getData();
-		String topic = new String(org.expeditee.auth.sharing.Actions.DecryptSymmetric(Base64.getDecoder().decode(data.get(3)), key));
-		String message = new String(org.expeditee.auth.sharing.Actions.DecryptSymmetric(Base64.getDecoder().decode(data.get(4)), key));
-		Map<String, String> options = new HashMap<String, String>();
-		for (int i = 5; i < data.size(); i+=2) {
-			String k = new String(org.expeditee.auth.sharing.Actions.DecryptSymmetric(Base64.getDecoder().decode(data.get(i)), key));
-			String v = new String(org.expeditee.auth.sharing.Actions.DecryptSymmetric(Base64.getDecoder().decode(data.get(i + 1)), key));
-			options.put(k, v);
-		}
-		MailBay.addMessage(data.get(0), topic, message, options);
-		StandardGestureActions.Refresh();
-	}
-	public static void SetPWColleagues(String colleagueOne, String colleagueTwo) {
-		Colleagues.Colleague_One.set(colleagueOne);
-		Colleagues.Colleague_Two.set(colleagueTwo);
-		Colleagues.Colleague_One_Email.set("bnemhauser@gmail.com");
-		Colleagues.Colleague_Two_Email.set("bnemhauser@gmail.com");
-	}
 	
 	private static String userbackup = "authadmin";
@@ -128,4 +107,20 @@
 		UserSettings.UserName.set(userbackup);
 		userbackup = backup;
+	}
+	//	End Debug Actions
+	
+	//	Start Misc Auth Actions
+	/**
+	 * Action ran by user to read a message using a single use distributed Symmetric key 
+	 * @param cursor The content on the cursor should be a text item whose content is the 
+	 * Symmetric key to use, represented as a Base64 encoded string.
+	 * @param actionItem The action item will contain the encrypted message in its data.
+	 */
+	public static void AuthOneOffSecureMessage(Text cursor, Text actionItem) {
+		byte[] keyBytes = Base64.getDecoder().decode(cursor.getText());
+		SecretKey key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
+		List<String> data = actionItem.getData();
+		Mail.decryptOneOffSecureMessage(key, data);
+		StandardGestureActions.Refresh();
 	}
 	
@@ -166,4 +161,114 @@
 	}
 	
+	/**
+	 * Action used to navigate to multiuser1 (multiuser abilities) if authenticated and authentication1 (login) is not so. 
+	 */
+	public static void AuthGotoAccountManagement() {
+		if (AuthenticatorBrowser.Authenticated) {
+			DisplayController.setCurrentFrame(FrameIO.LoadFrame("multiuser1"), false);
+		} else {
+			DisplayController.setCurrentFrame(FrameIO.LoadFrame("authentication1"), false);
+		}
+	}
+	
+	/**
+	 * Gets all items on a specified frame that contain the specified data.
+	 */
+	public static Collection<Item> getByData(Frame frame, String data) {
+		Collection<Item> allItems = frame.getAllItems();
+		allItems.removeIf(i -> i.getData() == null || !i.hasData(data));
+		return allItems;
+	}
+	
+	/**
+	 * Gets all items on a specified frame that contains the specified content.
+	 */
+	public static Collection<Item> getByContent(Frame frame, String content) {
+		Collection<Item> allItems = frame.getAllItems();
+		allItems.removeIf(i -> i.getText().compareTo(content) != 0);
+		return allItems;
+	}
+	//	End Misc Auth Actions
+	
+	//	Start Regain Account Access Actions 
+	/**
+	 * Action ran by user to specify who their password colleagues are.  These are the 
+	 * individuals who will be consulted if and when the user needs to regain access 
+	 * to their account.  
+	 * @param colleagueOne
+	 * @param colleagueTwo
+	 */
+	public static void AuthSetPWColleagues(String colleagueOne, String colleagueTwo) {
+		Password.setPWColleagues(colleagueOne, colleagueTwo);
+	}
+	
+	/**
+	 * Action ran by user to oblige with a request from colleague who has nominated the
+	 * user as a pw colleague.  Will email (not Expeditee mail) the colleague the password
+	 * share that the user has stored on their secrets frame. 
+	 * @param colleagueName
+	 */
+	public static void AuthEmailPasswordShare(String colleagueName) {
+		Password.emailPasswordShare(colleagueName);
+	}
+	
+	/**
+	 * Action ran by user to regain access to their account by providing:
+	 * 	their username
+	 * 	two password shares obtained from pw colleagues
+	 * 	their desired new password
+	 */
+	public static void AuthRegainAccountAccess() {
+		Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
+		Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, 
+				AuthenticationTag.Username, AuthenticationTag.NewPassword, AuthenticationTag.NewPasswordAgain, 
+				AuthenticationTag.PasswordSliceOne, AuthenticationTag.PasswordSliceTwo);
+		if (userdata.isPresent()) {
+			// Confirm new requested passwords match
+			Map<AuthenticationTag, String> userData = userdata.get();
+			if (!userData.get(AuthenticationTag.NewPassword).equals(userData.get(AuthenticationTag.NewPasswordAgain))) {
+				return;
+			}
+			
+			Password.regainAccountAccess(userData);
+		}
+	}
+		
+	/**
+	 * Actions used to generate and deliver an intergalactic number to a users public email
+	 * address after they have began the password recovery process.
+	 */
+	public static void AuthDistributeIntergalacticNumber() {
+		Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
+		Optional<Map<AuthenticationTag, String>> userdata = 
+				AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Username);
+		if (userdata.isPresent()) {
+			Map<AuthenticationTag, String> userData = userdata.get();
+			String username = userData.get(AuthenticationTag.Username);
+			String email = getEmailFromUsername(username);
+			userData.put(AuthenticationTag.Email, email);
+			Password.generateAndDeliverIntergalacticNumber(userData);
+			MessageBay.displayMessage("A identity number has been sent to the email "
+					+ "associated with your account.  Enter it below to proceed.");
+		}
+	}
+	
+	/**
+	 * Action used by user to submit their intergalactic number along with their username
+	 * in order to confirm that they own the public email address registered to their account.
+	 * This is part of the process of recoverying access to an account.
+	 */
+	public static void AuthSubmitIntergalacticNumber() {
+		Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
+		Optional<Map<AuthenticationTag, String>> userdata = 
+				AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Username, 
+						AuthenticationTag.IntergalacticNumber);
+		if (userdata.isPresent()) {
+			Password.confirmIntergalacticNumberAndAlertColleagues(userdata.get());
+		}
+	}
+	//	End Regain Account Access Actions 
+	
+	//	Start Create Account Actions
 	/**
 	 * Action used to created a new user account.
@@ -235,5 +340,7 @@
 		}
 	}
-	
+	//	End Create Account Actions
+	
+	//	Start Account Login Actions
 	/**
 	 * Action used to start authentication as a specified user.  
@@ -258,8 +365,13 @@
 	}
 	
+	/**
+	 * Action used by the user to log out of their account.
+	 */
 	public static void AuthLogout() {
 		MessageBay.displayMessage(Authenticate.logout().toString());
 	}
-	
+	//	End Account Login Actions
+	
+	//	Start Change Access Actions
 	/**
 	 * Action used to change the currently authenticated users password.
@@ -295,54 +407,12 @@
 		}
 	}
-	
-	public static void AuthGotoAccountManagement() {
-		if (AuthenticatorBrowser.Authenticated) {
-			DisplayController.setCurrentFrame(FrameIO.LoadFrame("multiuser1"), false);
-		} else {
-			DisplayController.setCurrentFrame(FrameIO.LoadFrame("authentication1"), false);
-		}
-	}
-	
-	public static void AuthDistributeIntergalacticNumber() {
-		Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
-		Optional<Map<AuthenticationTag, String>> userdata = 
-				AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Username);
-		if (userdata.isPresent()) {
-			Map<AuthenticationTag, String> userData = userdata.get();
-			String username = userData.get(AuthenticationTag.Username);
-			String email = getEmailFromUsername(username);
-			userData.put(AuthenticationTag.Email, email);
-			Password.generateAndDeliverIntergalacticNumber(userData);
-			MessageBay.displayMessage("A identity number has been sent to the email "
-					+ "associated with your account.  Enter it below to proceed.");
-		}
-	}
-	
-	public static void AuthSubmitIntergalacticNumber() {
-		Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
-		Optional<Map<AuthenticationTag, String>> userdata = 
-				AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Username, 
-						AuthenticationTag.IntergalacticNumber);
-		if (userdata.isPresent()) {
-			Map<AuthenticationTag, String> tags = userdata.get();
-			String username = tags.get(AuthenticationTag.Username);
-			String intergalacticNumber = tags.get(AuthenticationTag.IntergalacticNumber);
-			boolean match = false;
-			try {
-				match = AuthenticatorBrowser.getInstance().confirmIntergalaticNumber(username, intergalacticNumber);
-			} catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | ClassNotFoundException
-					| IOException | SQLException e) {
-				e.printStackTrace();
-				return;
-			}
-			if (!match) {
-				MessageBay.errorMessage("The provided identity number does not match the one stored on file.");
-				return;
-			}
-			String[] colleagues = getPasswordColleaguesFromUsername(username);
-			Password.confirmIntergalacticNumberAndAlertColleagues(userdata.get(), colleagues);
-		}
-	}
-	
+	// End Change Access Actions
+	
+	// Start Private Helper Functions.  
+	/**
+	 * Gets the public email address associated with the specified username.
+	 * @param username
+	 * @return
+	 */
 	private static String getEmailFromUsername(String username) {
 		Path credentialsDirPath = Paths.get(FrameIO.PROFILE_PATH).resolve(username).resolve(username + "-credentials");
@@ -374,43 +444,7 @@
 		}
 	}
-	
-	private static String[] getPasswordColleaguesFromUsername(String username) {
-		Path credentialsDirPath = Paths.get(FrameIO.PROFILE_PATH).resolve(username).resolve(username + "-credentials");
-		Path credentialsFilePath = credentialsDirPath.resolve("pwcolleagues.inf");
-		String fileName = null;
-		if (credentialsFilePath.toFile().exists()) {
-			try (Scanner in = new Scanner(credentialsFilePath)) {
-				fileName = in.nextLine();
-			} catch (IOException e) {
-				MessageBay.errorMessage("Unable to password colleague frame for specified user, are they registered on this computer?");
-				return null;
-			}
-		} else {
-			MessageBay.errorMessage("Unable to password colleague frame for specified user, are they registered on this computer?");
-			return null;
-		}
-		
-		int number = Integer.parseInt(fileName.replace(".exp", ""));
-		Frame pwColleagueFrame = FrameIO.LoadFrame(username + number, FrameIO.PROFILE_PATH);
-		Collection<Text> textItems = pwColleagueFrame.getTextItems();
-		textItems.removeIf(text -> !text.getText().startsWith("Colleague"));
-		
-		String[] ret = new String[4];
-		Iterator<Text> it = textItems.iterator();
-		while(it.hasNext()) {
-			String content = it.next().getText().toLowerCase().trim();
-			if (content.contains("colleague_one:")) {
-				ret[0] = content.replace("colleague_one:", "").trim();
-			} else if (content.contains("colleague_two:")) {
-				ret[1] = content.replace("colleague_two:", "").trim();
-			} else if (content.contains("colleague_one_email:")) {
-				ret[2] = content.replace("colleague_one_email:", "").trim();
-			} else if (content.contains("colleague_two_email:")) {
-				ret[3] = content.replace("colleague_two_email:", "").trim();
-			}
-		}
-		return ret;
-	}
-	
+	//	End Private Helper Functions.
+	
+	//	Start Future Functionality
 	public static void AuthShareFrameset() throws IOException {
 		Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
@@ -431,16 +465,23 @@
 		}
 	}
-
-	/**
-	 * Navigation action for progressing the process of recruiting colleagues to assist in password recovery.
-	 * Hides certain content that AuthSubmitPWCollegues goes onto show if it does not fail.
-	 */
-	public static void AuthGotoColleagueSubmissionFrame() {
-		Frame destination = FrameIO.LoadFrame("authentication7");
-		DisplayController.setCurrentFrame(destination, true);
-		Collection<Item> toHide = getByData(destination, "ShowOnProgress");
-		for (Item i: toHide) {
-			i.setVisible(false);
-		}
+	
+	/*
+	 * Function to share a specified frameset.
+	 * Currently, this moves the frameset to the 'Shared By Me' directory and then relies on the user to use Google Drive functionality to share it appropriately.
+	 */
+	private static void shareFrameset(Frame toShare) throws IOException {	
+		File destinationDir = new File(FrameIO.SHARED_FRAMESETS_PATH + File.separator + toShare.getFramesetName());
+		File sourceDir = new File(toShare.getFramesetPath());
+		
+		if (destinationDir.exists()) {
+			MessageBay.errorMessage("A frameset by this name already exists.");
+			return;
+		}
+		
+		destinationDir.mkdir();
+		List<Path> files = Files.walk(sourceDir.toPath()).collect(Collectors.toList());
+		Files.move(files.get(0), destinationDir.toPath(), StandardCopyOption.ATOMIC_MOVE);
+		
+		MessageBay.displayMessage("The frameset " + toShare.getFramesetName() + " has been moved to " + destinationDir + ".  Google Drive functionality can now be used to share it with colleagues.");
 	}
 	
@@ -493,65 +534,7 @@
 	}
 	
-//	public static void AuthSetupPasswordRecovery() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, IOException, SQLException, UnrecoverableEntryException {
-//		if (!UserSettings.Authenticated.get()) {
-//			MessageBay.errorMessage("You must be logged in to perform this action.");
-//		} else if (!Authenticator.getInstance().hasRegisteredEmail(UserSettings.UserName.get())) {
-//			Frame registerEmailFrame = FrameIO.LoadFrame("authentication4");
-//			DisplayController.setCurrentFrame(registerEmailFrame, true);
-//		} else if (!Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
-//			Frame submitColleaguesFrame = FrameIO.LoadFrame("authentication5");
-//			DisplayController.setCurrentFrame(submitColleaguesFrame, true);
-//		} else if (Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
-//			MessageBay.displayMessage("You have already nominated two colleagues to assist you in the process of password recovery and are awaiting their response."
-//					+ "  You will be alerted on Expeditee startup when they have both responded.");
-//		} else if (Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) != null) {
-//			MessageBay.displayMessage("You have completed the Password Recovery Setup process, there is nothing more to do here.");
-//		}
-//	}
-	
-	public static void AuthConfirmPasswordColleagueRelationship(String colleagueName) {
-		
-	}
-	
-	public static void AuthDenyPasswordColleagueRelationship(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, 
-		KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
-		denyPasswordColleagueRelationship(colleagueName);
-	}
-	
-	public static void AuthClearPWColleaguesNominated() {
-		
-	}
-	
 	/*
-	 * Function to share a specified frameset.
-	 * Currently, this moves the frameset to the 'Shared By Me' directory and then relies on the user to use Google Drive functionality to share it appropriately.
-	 */
-	private static void shareFrameset(Frame toShare) throws IOException {	
-		File destinationDir = new File(FrameIO.SHARED_FRAMESETS_PATH + File.separator + toShare.getFramesetName());
-		File sourceDir = new File(toShare.getFramesetPath());
-		
-		if (destinationDir.exists()) {
-			MessageBay.errorMessage("A frameset by this name already exists.");
-			return;
-		}
-		
-		destinationDir.mkdir();
-		List<Path> files = Files.walk(sourceDir.toPath()).collect(Collectors.toList());
-		Files.move(files.get(0), destinationDir.toPath(), StandardCopyOption.ATOMIC_MOVE);
-		
-		MessageBay.displayMessage("The frameset " + toShare.getFramesetName() + " has been moved to " + destinationDir + ".  Google Drive functionality can now be used to share it with colleagues.");
-	}
-	
-	private static void denyPasswordColleagueRelationship(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
-		String time = org.expeditee.stats.Formatter.getDateTime();
-		String sender = UserSettings.UserName.get();
-		String message = "You have received a reply from " + sender + " reguarding your request for assistance.";
-		String message2 = "Unfortunately " + sender + " has indicated that they are unable to help you with your potential password recovery.";
-		Map<String, String> options = new HashMap<String, String>();
-		options.put("Clear Preview Colleague Nominations", "AuthClearPWColleaguesNominated");
-		MailEntry mail = new MailEntry(time, sender, colleagueName, message, message2, options);
-		Mail.sendMail(mail, colleagueName);
-	}
-	
+	 * Function to submit a request to specified contacts to be the current users pw colleagues.
+	 */
 	private static boolean submitPWColleagues(Map<AuthenticationTag, String> userData) throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
 		String colleagueOne = userData.get(AuthenticationTag.ColleagueOne);
@@ -581,26 +564,4 @@
 		}
 	}
-	
-	public static void TickBox(final Text item) {
-		if (item.getBackgroundColor() != Colour.RED) {
-			item.setBackgroundColor(Colour.RED);
-		} else {
-			item.setBackgroundColor(Colour.GREEN);
-		}
-	}
-	
-	/*
-	 * Gets all items on a specified frame that contain the specified data.
-	 */
-	public static Collection<Item> getByData(final Frame frame, final String data) {
-		final Collection<Item> allItems = frame.getAllItems();
-		allItems.removeIf(i -> i.getData() == null || !i.hasData(data));
-		return allItems;
-	}
-	
-	public static Collection<Item> getByContent(final Frame frame, final String content) {
-		final Collection<Item> allItems = frame.getAllItems();
-		allItems.removeIf(i -> i.getText().compareTo(content) != 0);
-		return allItems;
-	}
+	// End Future Functionality
 }
Index: trunk/src/org/expeditee/auth/AuthenticatorBrowser.java
===================================================================
--- trunk/src/org/expeditee/auth/AuthenticatorBrowser.java	(revision 1362)
+++ trunk/src/org/expeditee/auth/AuthenticatorBrowser.java	(revision 1363)
@@ -44,4 +44,5 @@
 
 import org.expeditee.actions.Actions;
+import org.expeditee.auth.mail.Mail;
 import org.expeditee.core.Dimension;
 import org.expeditee.core.Point;
@@ -73,4 +74,5 @@
 	public static int CREDENTIALS_FRAME = -1;
 	public static int PASSWORD_RECOVERY_FRAME = -1;
+	public static int SECRETS_FRAME = -1;
 	public static final String ADMINACCOUNT = "authadmin";
 	public static final String PROFILEENCRYPTIONLABEL = "Profile";
@@ -107,5 +109,5 @@
 		loadKeystore();
 		Actions.LoadMethods(org.expeditee.auth.Actions.class);
-		Actions.LoadMethods(org.expeditee.auth.sharing.Actions.class);
+		Actions.LoadMethods(org.expeditee.encryption.Actions.class);
 
 		// Does the account Authentication.ADMINACCOUNT exist?
@@ -351,5 +353,5 @@
 		// generate intergalactic number
 		SecureRandom rand = new SecureRandom();
-		byte[] intergalacticNumberBytes = new byte[10];
+		byte[] intergalacticNumberBytes = new byte[16];
 		rand.nextBytes(intergalacticNumberBytes);
 		String intergalacticNumber = Base64.getEncoder().encodeToString(intergalacticNumberBytes);
Index: trunk/src/org/expeditee/auth/Mail.java
===================================================================
--- trunk/src/org/expeditee/auth/Mail.java	(revision 1362)
+++ 	(revision )
@@ -1,370 +1,0 @@
-package org.expeditee.auth;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.security.InvalidKeyException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.security.spec.InvalidKeySpecException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import org.expeditee.auth.gui.MailBay;
-import org.expeditee.gui.FrameIO;
-import org.expeditee.settings.UserSettings;
-import org.ngikm.cryptography.CryptographyConstants;
-
-public class Mail implements CryptographyConstants {
-	
-	private static List<MailEntry> messages = new ArrayList<MailEntry>();
-	
-	/**
-	 * Add a piece of mail, used during initialisation.
-	 */
-	public static void addEntry(MailEntry mail) {
-		messages.add(mail);
-	}
-	
-	public static void clear() {
-		messages.clear();
-	}
-	
-	public static void sendOneOffMail(MailEntry mail, String colleagueName, byte[] key) {
-		// Ensure dead drop area is set up.
-		Path databaseFileDirPath = ensureDeadDrops(colleagueName);
-		
-		// Ensure the database file exists.
-		Path databaseFilePath = ensureDatabaseFile(colleagueName, databaseFileDirPath);
-		
-		// Create secret key.
-		SecretKey secretKey = new SecretKeySpec(key, SymmetricAlgorithm);
-		
-		// Send message
-		sendMail(mail, secretKey, databaseFilePath);
-	}
-	
-	public static void sendMail(MailEntry mail, String colleagueName) {
-		// Ensure dead drop area is set up.
-		Path databaseFileDirPath = ensureDeadDrops(colleagueName);
-		
-		// Ensure the database file exists.
-		Path databaseFilePath = ensureDatabaseFile(colleagueName, databaseFileDirPath);
-		
-		// Obtain public key
-		PublicKey publicKey = null;
-		try {
-			publicKey = AuthenticatorBrowser.getInstance().getPublicKey(colleagueName);
-		} catch (InvalidKeySpecException | NoSuchAlgorithmException | KeyStoreException | CertificateException
-				| ClassNotFoundException | IOException | SQLException e) {
-			System.err.println("Error while sending message.  Unable to obtain public key for colleague " +  
-				colleagueName + ".  Exception message: " + e.getMessage());
-			return;
-		}
-		
-		// Check we got public key
-		if (publicKey == null) {
-			System.err.println("Error while sending message.  Unable to obtain public key for colleague.  Have you exchanged contact details?");
-			return;
-		}
-		
-		// Send message
-		sendMail(mail, publicKey, databaseFilePath);
-	}
-
-	private static Path ensureDatabaseFile(String colleagueName, Path databaseFileDirPath) {
-		Path databaseFilePath = databaseFileDirPath.resolve(colleagueName + ".db");
-		File databaseFile = databaseFilePath.toFile();
-		if (!databaseFile.exists()) {
-			databaseFileDirPath.toFile().mkdirs();
-			String sql = 
-					"CREATE TABLE EXPMAIL (" +
-					"TIME		TEXT					NOT NULL, " +
-					"SND		TEXT					NOT NULL, " + 
-					"REC		TEXT					NOT NULL, " + 
-					"MSG		TEXT					NOT NULL, " +
-					"MSG2		TEXT					NOT NULL, " + 
-					"OPTS		ARRAY					NOT NULL, " +
-					"OPTSVAL	ARRAY					NOT NULL)";
-			try {
-				Connection c = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getAbsolutePath());
-				Statement createTable = c.createStatement();
-				createTable.executeUpdate(sql);
-				createTable.close();
-				c.close();
-			} catch (SQLException e) {
-				System.err.println("Error while creating database file.");
-				e.printStackTrace();
-			}
-		}
-		return databaseFilePath;
-	}
-
-	private static Path ensureDeadDrops(String colleagueName) {
-		String me = UserSettings.UserName.get().toLowerCase();
-		String them = colleagueName.toLowerCase();
-		Path databaseFileDirPath = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(me + "+" + them);
-		if (!databaseFileDirPath.toFile().exists()) {
-			databaseFileDirPath = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(them + "+" + me);
-		}
-		return databaseFileDirPath;
-	}
-	
-	private static void sendMail(MailEntry mail, PublicKey key, Path databaseFile) {
-		try {
-			Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String sender = Base64.getEncoder().encodeToString(cipher.doFinal(mail.sender.getBytes()));
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String rec = Base64.getEncoder().encodeToString(cipher.doFinal(mail.receiver.getBytes()));
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String message = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message.getBytes()));
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String message2 = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message2.getBytes()));
-			
-			Map<String, String> options = new HashMap<String, String>(); 
-			for (String label: mail.options.keySet()) {
-				cipher.init(Cipher.ENCRYPT_MODE, key);
-				String labelEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(label.getBytes()));
-				cipher.init(Cipher.ENCRYPT_MODE, key);
-				String actionNameEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(mail.options.get(label).getBytes()));
-				options.put(labelEncrypted, actionNameEncrypted);
-			}
-			
-			// write to mail database
-			writeToMailDatabase(mail, databaseFile, sender, rec, message, message2, options);			
-		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | SQLException e) {
-			e.printStackTrace();
-		}
-	}
-	
-	private static void sendMail(MailEntry mail, SecretKey key, Path databaseFile) {
-		try {
-			//	Encrypt message.
-			Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String sender = "=" + Base64.getEncoder().encodeToString(cipher.doFinal(mail.sender.getBytes()));
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String rec = Base64.getEncoder().encodeToString(cipher.doFinal(mail.receiver.getBytes()));
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String message = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message.getBytes()));
-			cipher.init(Cipher.ENCRYPT_MODE, key);
-			String message2 = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message2.getBytes()));			
-			Map<String, String> options = new HashMap<String, String>(); 
-			for (String label: mail.options.keySet()) {
-				cipher.init(Cipher.ENCRYPT_MODE, key);
-				String labelEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(label.getBytes()));
-				cipher.init(Cipher.ENCRYPT_MODE, key);
-				String actionNameEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(mail.options.get(label).getBytes()));
-				options.put(labelEncrypted, actionNameEncrypted);
-			}
-			
-			//	Write to mail database.
-			writeToMailDatabase(mail, databaseFile, sender, rec, message, message2, options);
-		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | SQLException e) {
-			e.printStackTrace();
-		}
-	}
-
-	private static void writeToMailDatabase(MailEntry mail, Path databaseFile, String sender, String rec,
-			String message, String message2, Map<String, String> options) throws SQLException {
-		Connection c = DriverManager.getConnection("jdbc:sqlite:" + databaseFile);
-		String sql = "INSERT INTO EXPMAIL (TIME,SND,REC,MSG,MSG2,OPTS,OPTSVAL) VALUES (?, ?, ?, ?, ?, ?, ?);";
-		PreparedStatement statement = c.prepareStatement(sql);
-		statement.setString(1, mail.timestamp);
-		statement.setString(2, sender);
-		statement.setString(3, rec);
-		statement.setString(4, message);
-		statement.setString(5, message2);
-		String opts = Arrays.toString(options.keySet().toArray());
-		statement.setString(6, opts);
-		String optsval = Arrays.toString(options.values().toArray());
-		statement.setString(7, optsval);
-		statement.execute();
-		statement.close();
-		c.close();
-	}
-		
-	/**
-	 * Gets the mail messages that the specified user is able to read.
-	 * The caller supplies their username and private key.  
-	 * If the private key can decrypt a message, then it was encrypted using the users public key, and is therefore for them.
-	 */
-	private static List<MailEntry> getEntries(String name, PrivateKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
-		List<MailEntry> filtered = new ArrayList<MailEntry>();
-		
-		for (MailEntry mail: messages) {
-			if (isEncryptedOneOffMessage(mail)) {
-				getOneOffSecureMail(name, filtered, mail);
-			} else {
-				getStandardSecureMail(name, key, filtered, mail);
-			}
-		}
-		
-		return filtered;
-	}
-
-	private static void getOneOffSecureMail(String name, List<MailEntry> filtered, MailEntry mail) {
-		StringBuilder sb = new StringBuilder();
-		String sep = ":::";
-		sb.append("Read one-off secure message." + sep);
-		sb.append(mail.timestamp + sep);
-		sb.append(mail.sender + sep);
-		sb.append(mail.receiver + sep);
-		sb.append(mail.message + sep);
-		sb.append(mail.message2 + sep);
-		for (String k: mail.options.keySet()) {
-			sb.append(k + sep + mail.options.get(k) + sep);
-		}
-		sb.reverse().delete(0, 3).reverse();
-		Map<String, String> options = new HashMap<String, String>();
-		options.put(sb.toString(), "AuthOneOffSecureMessage");
-		String currentTime = org.expeditee.stats.Formatter.getDateTime();
-		MailEntry mailOuter = new MailEntry(currentTime, "Unknown", name, "You have received a one-off secure message.", "Check your email for more details.", options);
-		
-		if (mail.deadDropSource != null) {
-			Path lastAccessedFile = mail.deadDropSource.getParent().resolve(name + ".last-accessed");
-			SimpleDateFormat format = new SimpleDateFormat("ddMMMyyyy[HH:mm]");
-			try (Scanner in = new Scanner(lastAccessedFile.toFile())) {
-				Date lastAccessedTimestamp = format.parse(in.nextLine());
-				Date mailTimestamp = format.parse(mail.timestamp);
-				if (mailTimestamp.after(lastAccessedTimestamp)) {
-					filtered.add(mailOuter);
-				}
-			} catch (FileNotFoundException e) {
-				// It may not have been created yet, then err on the safe side and add it in.
-				filtered.add(mailOuter);
-			} catch (ParseException e) {
-				// If we fail to parse, then err on the safe side and add it in.
-				filtered.add(mailOuter);
-			}
-		}
-	}
-
-	private static void getStandardSecureMail(String name, PrivateKey key, List<MailEntry> filtered, MailEntry mail)
-			throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, InvalidKeyException,
-			BadPaddingException {
-		// confirm this is a message for the requester of entries
-		String receiver = mail.receiver;
-		byte[] receiverBytes = Base64.getDecoder().decode(receiver);
-		String receiverDecrypted = null;
-		Cipher c = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
-		try {
-			c.init(Cipher.DECRYPT_MODE, key);
-			receiverDecrypted = new String(c.doFinal(receiverBytes));
-		} catch (InvalidKeyException | BadPaddingException e) {
-			return;
-		}
-		
-		// add an unencrypted version of the message to the return list
-		if (receiverDecrypted.compareToIgnoreCase(name) == 0) {
-			c.init(Cipher.DECRYPT_MODE, key);
-			String sender = new String(c.doFinal(Base64.getDecoder().decode(mail.sender)));
-			c.init(Cipher.DECRYPT_MODE, key);
-			String message = new String(c.doFinal(Base64.getDecoder().decode(mail.message)));
-			c.init(Cipher.DECRYPT_MODE, key);
-			String message2 = new String(c.doFinal(Base64.getDecoder().decode(mail.message2)));
-			
-			Map<String, String> options = new HashMap<String, String>();
-			for (String label: mail.options.keySet()) {
-				c.init(Cipher.DECRYPT_MODE, key);
-				String labelDecrypted = new String(c.doFinal(Base64.getDecoder().decode(label)));
-				c.init(Cipher.DECRYPT_MODE, key);
-				String actionNameDecrypted = new String(c.doFinal(Base64.getDecoder().decode(mail.options.get(label))));
-				options.put(labelDecrypted, actionNameDecrypted);
-			}
-			
-			Path lastAccessedFile = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(UserSettings.UserName.get() + "+" + sender).resolve(name + ".last-accessed");
-			if (!lastAccessedFile.toFile().exists()) {
-				lastAccessedFile = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(sender + "+" + UserSettings.UserName.get()).resolve(name + ".last-accessed");
-			}
-			SimpleDateFormat format = new SimpleDateFormat("ddMMMyyyy[HH:mm]");
-			MailEntry mailEntry = new MailEntry(mail.timestamp, sender, receiverDecrypted, message, message2, options);
-			try (Scanner in = new Scanner(lastAccessedFile.toFile())) {
-				Date lastAccessedTimestamp = format.parse(in.nextLine());
-				Date mailTimestamp = format.parse(mail.timestamp);
-				if (mailTimestamp.after(lastAccessedTimestamp)) {
-					filtered.add(mailEntry);
-				}
-			} catch (FileNotFoundException e) {
-				// It may not have been created yet, then err on the safe side and add it in.
-				filtered.add(mailEntry);
-			} catch (ParseException e) {
-				// If we fail to parse, then err on the safe side and add it in.
-				filtered.add(mailEntry);
-			}			
-			
-		}
-	}
-	
-	private static boolean isEncryptedOneOffMessage(MailEntry mail) {
-		return mail.sender.charAt(0) == '=';
-	}
-	
-	/**
-	 * Describes a piece of mail, either encrypted or decrypted.
-	 */
-	public static class MailEntry {
-		public String timestamp;
-		public String sender;
-		public String receiver;
-		public String message;
-		public String message2;
-		public Map<String, String> options;
-		public Path deadDropSource;
-		
-		public MailEntry(String timestamp, String sender, String rec, String message, String message2, Map<String, String> options) {
-			this.timestamp = timestamp;
-			this.sender = sender;
-			this.receiver = rec;
-			this.message = message;
-			this.message2 = message2;
-			this.options = options;
-		}
-	}
-
-	public static void checkMail(PrivateKey key) throws NoSuchAlgorithmException, NoSuchPaddingException,
-			IllegalBlockSizeException, BadPaddingException, InvalidKeyException, KeyStoreException,
-			FileNotFoundException, CertificateException, IOException, ClassNotFoundException, SQLException, ParseException {
-		MailBay.clear();
-		AuthenticatorBrowser.getInstance().loadMailDatabase();
-		List<MailEntry> mailForLoggingInUser = Mail.getEntries(UserSettings.UserName.get(), key);			
-		for (MailEntry mail: mailForLoggingInUser) {
-			MailBay.addMessage(mail.timestamp, mail.message, mail.message2, mail.options);
-		}
-		
-		// Update last read files.
-		Path deadDropPath = Paths.get(FrameIO.DEAD_DROPS_PATH);
-		for (File connectionDir: deadDropPath.toFile().listFiles()) {
-			if (connectionDir.isDirectory()) {
-				Path deaddropforcontactPath = Paths.get(connectionDir.getAbsolutePath());
-				AuthenticatorBrowser.getInstance().updateLastReadMailTime(deaddropforcontactPath);
-			}
-		}
-	}
-}
Index: trunk/src/org/expeditee/auth/account/Authenticate.java
===================================================================
--- trunk/src/org/expeditee/auth/account/Authenticate.java	(revision 1362)
+++ trunk/src/org/expeditee/auth/account/Authenticate.java	(revision 1363)
@@ -25,5 +25,5 @@
 import org.expeditee.auth.Actions;
 import org.expeditee.auth.AuthenticatorBrowser;
-import org.expeditee.auth.gui.MailBay;
+import org.expeditee.auth.mail.gui.MailBay;
 import org.expeditee.auth.tags.AuthenticationTag;
 import org.expeditee.gui.Browser;
@@ -41,4 +41,9 @@
 public class Authenticate implements CryptographyConstants {
 
+	/**
+	 * Given a username and password, potentially login.  
+	 * @param userdata
+	 * @return AuthenticationResult.SuccessLogin if login works, AuthenticationResult.ErrorLoginNobody or AuthenticationResult.ErrorLoginUsernamePasswordCombo otherwise.
+	 */
 	public static AuthenticationResult login(Map<AuthenticationTag, String> userdata) {
 		String username = userdata.get(AuthenticationTag.Username);
@@ -76,6 +81,10 @@
 					if(data != null && data.contains("MultiuserCredentials")) {
 						AuthenticatorBrowser.CREDENTIALS_FRAME = f.getNumber();
+					} else if (data != null && data.contains("PasswordColleagues")) {
+						AuthenticatorBrowser.PASSWORD_RECOVERY_FRAME = f.getNumber();
+					} else if (data != null && data.contains("SecretsFrame")) {
+						AuthenticatorBrowser.SECRETS_FRAME = f.getNumber();
 					}
-				}
+ 				}
 			}
 			
@@ -103,5 +112,5 @@
 					byte[] keyBytes = Base64.getDecoder().decode(keyEncoded);
 					PrivateKey key = KeyFactory.getInstance(AsymmetricAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
-					org.expeditee.auth.Mail.checkMail(key);
+					org.expeditee.auth.mail.Mail.checkMail(key);
 				} else {
 					res.additionalInfo.add("No private key present: your communication with other Expeditee users will be limited until this is resolved.");
@@ -129,4 +138,8 @@
 	}
 	
+	/**
+	 * Logs out the current authenticated user.
+	 * @return AuthenticationResult.SuccessLogout to signal the logout has occured.
+	 */
 	public static AuthenticationResult logout() {
 		// Set user to nobody.
Index: trunk/src/org/expeditee/auth/account/Create.java
===================================================================
--- trunk/src/org/expeditee/auth/account/Create.java	(revision 1362)
+++ trunk/src/org/expeditee/auth/account/Create.java	(revision 1363)
@@ -125,11 +125,5 @@
 		return CreateResult.SuccessCreateAccount;
 	}
-	
-	public static CreateResult createAlternativeAccess(Map<AuthenticationTag, String> userdata) {
-		String username = userdata.get(AuthenticationTag.Username);
-		FrameIO.CreateFrame(username, null, "default1");
-		return null;
-	}
-		
+			
 	public enum CreateResult {
 		SuccessCreateAccount ("Account created."), 
@@ -193,6 +187,5 @@
 			FrameIO.migrateFrame(credentialsFrame, destinationFile);
 			//	pwcolleagues.inf file.
-			String pwColleaguesPath = credentialsDir.getAbsolutePath() + File.separator + "pwcolleagues.inf";
-			File pwColleaguesFile = new File(pwColleaguesPath);
+			File pwColleaguesFile = Paths.get(FrameIO.PROFILE_PATH).resolve(username).resolve("pwcolleagues.inf").toFile();
 			pwColleaguesFile.createNewFile();
 			out = new FileWriter(pwColleaguesFile);
@@ -234,8 +227,12 @@
 			}
 		});
-		notifiers.put("settings.identity.passwordrecovery", frame -> { 
+		notifiers.put("settings.identity.passwordrecovery", frame -> {
+			frame.addToData("PasswordColleagues");
 			AuthenticatorBrowser.PASSWORD_RECOVERY_FRAME = frame.getNumber();
 		});
-		
+		notifiers.put("settings.identity.secrets", frame -> {
+			frame.addToData("SecretsFrame");
+			AuthenticatorBrowser.SECRETS_FRAME = frame.getNumber();
+ 		});
 		
 		// Create users profile
Index: trunk/src/org/expeditee/auth/account/Password.java
===================================================================
--- trunk/src/org/expeditee/auth/account/Password.java	(revision 1362)
+++ trunk/src/org/expeditee/auth/account/Password.java	(revision 1363)
@@ -1,14 +1,24 @@
 package org.expeditee.auth.account;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 import java.security.cert.CertificateException;
 import java.sql.SQLException;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Scanner;
 
 import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
 import javax.mail.Message;
 import javax.mail.MessagingException;
@@ -16,17 +26,28 @@
 import javax.mail.Session;
 import javax.mail.Transport;
+import javax.mail.internet.AddressException;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 
 import org.expeditee.auth.AuthenticatorBrowser;
+import org.expeditee.auth.mail.Mail;
+import org.expeditee.auth.mail.Mail.MailEntry;
 import org.expeditee.auth.tags.AuthenticationTag;
 import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.MessageBay;
+import org.expeditee.items.Text;
+import org.expeditee.settings.UserSettings;
+import org.expeditee.settings.identity.passwordrecovery.Colleagues;
+import org.expeditee.settings.identity.secrets.KeyList;
+import org.expeditee.stats.Formatter;
 import org.ngikm.cryptography.CryptographyConstants;
 
+import com.codahale.shamir.Scheme;
+
 public class Password implements CryptographyConstants {
-	/*
-	 * Changes the recorded password for a user in the key store.
+	/**
+	 * Changes the recorded password for a user in the key store; given the username signaling whose password to change, along with the existing and new password.
 	 */
 	public static void changePassword(Map<AuthenticationTag, String> userdata) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, IOException, ClassNotFoundException, SQLException {
@@ -45,4 +66,8 @@
 	}
 
+	/**
+	 * Generates a intergalaictic number for a specified user and emails that number using the specified email.
+	 * @param userData
+	 */
 	public static void generateAndDeliverIntergalacticNumber(Map<AuthenticationTag, String> userData) {
 		String username = userData.get(AuthenticationTag.Username);
@@ -57,33 +82,5 @@
 			sb.append("If it was you who made this request, the following string of characters is your intergalactic number: " + intergalacticNumber + nl);
 			
-			// Establish properties for email.
-			Properties properties = System.getProperties();
-			properties.setProperty("mail.transport.protocol", "smtp");
-			properties.setProperty("mail.smtp.host", "smtp.gmail.com");
-			properties.setProperty("mail.smtp.port", "465");
-			properties.setProperty("mail.smtp.starttls.enable", "true");
-			properties.setProperty("mail.smtp.auth", "true");
-			properties.setProperty("mail.smtp.debug", "true");
-			properties.setProperty("mail.smtp.auth", "true");
-			properties.setProperty("mail.smtp.socketFactory.port", "465");
-			properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
-			properties.setProperty("mail.smtp.socketFactory.fallback", "false");
-			
-			Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() {
-				@Override
-				protected PasswordAuthentication getPasswordAuthentication() {
-					return new PasswordAuthentication("noreply.expeditee", "intergalacticnumber");
-				};
-			});
-			
-			// construct email message
-			final MimeMessage message = new MimeMessage(session);
-			message.setFrom(new InternetAddress("noreply@expeditee.com"));
-			message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
-			message.setSubject("Expeditee Password Recovery");
-			message.setText(sb.toString());
-			
-			// send email message
-			Transport.send(message);		
+			sendEmail(email, sb);		
 		} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | ClassNotFoundException
 				| IOException | SQLException | MessagingException e) {
@@ -92,7 +89,266 @@
 	}
 	
-	public static void confirmIntergalacticNumberAndAlertColleagues(Map<AuthenticationTag, String> userData, String[] colleagues) {
-		System.err.println("Colleague One: " + colleagues[0] + " @" + colleagues[2]);
-		System.err.println("Colleague Two: " + colleagues[1] + " @" + colleagues[3]);
+	/**
+	 * Confirms that the specified intergalaictic number matches the one of file for the specified username.
+	 * Passing this test it then alerts the users pw colleagues through a one-off secure Expeditee message.
+	 * @param tags
+	 */
+	public static void confirmIntergalacticNumberAndAlertColleagues(Map<AuthenticationTag, String> tags) {
+		// Confirm intergalactic numbers match
+		String username = tags.get(AuthenticationTag.Username);
+		String intergalacticNumber = tags.get(AuthenticationTag.IntergalacticNumber);
+		boolean match = false;
+		try {
+			match = AuthenticatorBrowser.getInstance().confirmIntergalaticNumber(username, intergalacticNumber);
+		} catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | ClassNotFoundException
+				| IOException | SQLException e) {
+			e.printStackTrace();
+			return;
+		}
+		if (!match) {
+			MessageBay.errorMessage("The provided identity number does not match the one stored on file.");
+			return;
+		}
+		
+		// Get colleagues to distribute messages too.
+		String[] colleagues = getPasswordColleaguesFromUsername(username);
+		// 	Send secure message to colleague one
+		String colleagueOne = colleagues[0];
+		String time = Formatter.getDateTime();
+		String topic = "Password Recovery for " + username;
+		String message = "Your colleague " + username + " would like you to help them recover access to their account.";
+		Map<String, String> options = new HashMap<String, String>();
+		options.put("Provide assistance", "AuthEmailPasswordShare " + username); 
+		MailEntry mail = new MailEntry(time, username, colleagueOne, topic, message, options);
+		Mail.sendOneOffMail(mail, colleagueOne, Base64.getDecoder().decode(intergalacticNumber));
+		
+		//	Send secure message to colleague two
+		String colleagueTwo = colleagues[1];
+		Mail.sendOneOffMail(mail, colleagueTwo, Base64.getDecoder().decode(intergalacticNumber));
+		
+		String nl = System.getProperty("line.separator");
+		StringBuilder sb = new StringBuilder();
+		sb.append("You are receiving this email because one of your Expeditee contacts has sent you a one-off secure message." + nl);
+		sb.append("When you log into Expeditee and check your mail it will be there waiting for you." + nl);
+		sb.append("You will need the following key to read this message: " + nl);
+		sb.append(intergalacticNumber);
+		try {
+			//	Send email with key to colleague one
+			String colleagueOneEmail = colleagues[2];
+			sendEmail(colleagueOneEmail, sb);
+			//	Send email with key to colleague two
+			String colleagueTwoEmail = colleagues[3];
+			sendEmail(colleagueTwoEmail, sb);
+		} catch (MessagingException e) {
+			e.printStackTrace();
+		}		
+	}
+	
+	private static String[] getPasswordColleaguesFromUsername(String username) {
+		Path credentialsFilePath = Paths.get(FrameIO.PROFILE_PATH).resolve(username).resolve("pwcolleagues.inf");
+		String fileName = null;
+		if (credentialsFilePath.toFile().exists()) {
+			try (Scanner in = new Scanner(credentialsFilePath)) {
+				fileName = in.nextLine();
+			} catch (IOException e) {
+				MessageBay.errorMessage("Unable to password colleague frame for specified user, are they registered on this computer?");
+				return null;
+			}
+		} else {
+			MessageBay.errorMessage("Unable to password colleague frame for specified user, are they registered on this computer?");
+			return null;
+		}
+		
+		int number = Integer.parseInt(fileName.replace(".exp", ""));
+		Frame pwColleagueFrame = FrameIO.LoadFrame(username + number, FrameIO.PROFILE_PATH);
+		Collection<Text> textItems = pwColleagueFrame.getTextItems();
+		textItems.removeIf(text -> !text.getText().startsWith("Colleague"));
+		
+		String[] ret = new String[4];
+		Iterator<Text> it = textItems.iterator();
+		while(it.hasNext()) {
+			String content = it.next().getText().toLowerCase().trim();
+			if (content.contains("colleague_one:")) {
+				ret[0] = content.replace("colleague_one:", "").trim();
+			} else if (content.contains("colleague_two:")) {
+				ret[1] = content.replace("colleague_two:", "").trim();
+			}
+		}
+				
+		// find colleague one email
+		Path credentialsDirectoryPath = UserSettings.PublicAndPrivateResources 
+				? Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-" + username)
+				: Paths.get(FrameIO.PARENT_FOLDER);
+		credentialsDirectoryPath = credentialsDirectoryPath.resolve("contacts").resolve(ret[0] + "-credentials");
+		try (Scanner in = new Scanner(credentialsDirectoryPath.resolve("credentials.inf").toFile())) {
+			int parseInt = Integer.parseInt(in.nextLine().replace(".exp", ""));
+			Frame frame = FrameIO.LoadFrame(ret[0] + "-credentials" + parseInt, credentialsDirectoryPath.toAbsolutePath().getParent().toString() + File.separator);
+			textItems = frame.getTextItems();
+			textItems.removeIf(text -> !text.getText().startsWith("Email:"));
+			ret[2] = textItems.iterator().next().getText().replace("Email:", "").trim();
+		} catch (FileNotFoundException e) {
+			MessageBay.errorMessage("You do not appear to have contact with your nominated password colleague: " + ret[0]);
+			return null;
+		}
+		
+		
+		// find colleague two email
+		credentialsDirectoryPath = UserSettings.PublicAndPrivateResources 
+				? Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-" + username)
+				: Paths.get(FrameIO.PARENT_FOLDER);
+		credentialsDirectoryPath = credentialsDirectoryPath.resolve("contacts").resolve(ret[1] + "-credentials");
+		try (Scanner in = new Scanner(credentialsDirectoryPath.resolve("credentials.inf").toFile())) {
+			int parseInt = Integer.parseInt(in.nextLine().replace(".exp", ""));
+			Frame frame = FrameIO.LoadFrame(ret[1] + "-credentials" + parseInt, credentialsDirectoryPath.toAbsolutePath().getParent().toString() + File.separator);
+			textItems = frame.getTextItems();
+			textItems.removeIf(text -> !text.getText().startsWith("Email:"));
+			ret[3] = textItems.iterator().next().getText().replace("Email:", "").trim();
+		} catch (FileNotFoundException e) {
+			MessageBay.errorMessage("You do not appear to have contact with your nominated password colleague: " + ret[1]);
+			return null;
+		}
+		
+		return ret;
+	}
+	
+
+	public static void sendEmail(String email, StringBuilder sb) throws MessagingException, AddressException {
+		// Establish properties for email.
+		Properties properties = System.getProperties();
+		properties.setProperty("mail.transport.protocol", "smtp");
+		properties.setProperty("mail.smtp.host", "smtp.gmail.com");
+		properties.setProperty("mail.smtp.port", "465");
+		properties.setProperty("mail.smtp.starttls.enable", "true");
+		properties.setProperty("mail.smtp.auth", "true");
+		properties.setProperty("mail.smtp.debug", "true");
+		properties.setProperty("mail.smtp.auth", "true");
+		properties.setProperty("mail.smtp.socketFactory.port", "465");
+		properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+		properties.setProperty("mail.smtp.socketFactory.fallback", "false");
+		
+		Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() {
+			@Override
+			protected PasswordAuthentication getPasswordAuthentication() {
+				return new PasswordAuthentication("noreply.expeditee", "intergalacticnumber");
+			};
+		});
+		
+		// construct email message
+		final MimeMessage message = new MimeMessage(session);
+		message.setFrom(new InternetAddress("noreply@expeditee.com"));
+		message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
+		message.setSubject("Expeditee Password Recovery");
+		message.setText(sb.toString());
+		
+		// send email message
+		Transport.send(message);
+	}
+
+	public static void setPWColleagues(String colleagueOne, String colleagueTwo) {
+		// Get needed text items.
+		Frame pwRecoveryFrame = FrameIO.LoadFrame(UserSettings.UserName.get() + AuthenticatorBrowser.PASSWORD_RECOVERY_FRAME);
+		Collection<Text> textItems = pwRecoveryFrame.getTextItems();
+		textItems.removeIf(t -> !t.getText().toLowerCase().startsWith("colleague"));
+		
+		// Find colleague one and two text items.  Set appropriate values.
+		Iterator<Text> it = textItems.iterator();
+		while (it.hasNext()) {
+			Text text = it.next();
+			if (text.getText().toLowerCase().startsWith("colleague_one:")) {
+				text.setText("Colleague_one: " + colleagueOne);
+				Colleagues.Colleague_One.set(colleagueOne);
+			} else if (text.getText().toLowerCase().startsWith("colleague_two:")) {
+				text.setText("Colleague_two:" + colleagueTwo);
+				Colleagues.Colleague_Two.set(colleagueTwo);
+			}
+		}
+		FrameIO.ForceSaveFrame(pwRecoveryFrame);
+		
+		// Key to split and distribute
+		String fullKey = KeyList.PersonalKey.get().getData().get(0);
+		byte[] keyBytes = Base64.getDecoder().decode(fullKey);
+		
+		// Initialise Shamir
+		int totalShares = 2;
+		int requiredShares = 2;
+		Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares);
+		
+		// Create shares
+		Map<Integer, byte[]> shares = scheme.split(keyBytes);
+		String colleagueOneShare = Base64.getEncoder().encodeToString(shares.get(1));
+		String colleagueTwoShare = Base64.getEncoder().encodeToString(shares.get(2));
+		
+		// Distribute share zero to colleague one
+		String time = org.expeditee.stats.Formatter.getDateTime();
+		String sender = UserSettings.UserName.get();
+		String topic = "Please help me secure my Expeditee account.";
+		String message = "Run the below action to store a secret key that will help me recover access to my account should I ever loose it.";
+		Map<String, String> options = new HashMap<String, String>();
+		options.put("Store Secret Key for " + sender, "AuthAddSecretKey " + sender + "PersonalKeyShare " + colleagueOneShare);
+		MailEntry mail = new MailEntry(time, sender, colleagueOne, topic, message, options);
+		Mail.sendMail(mail, colleagueOne);
+		
+		// Distribute share one to colleague two
+		options = new HashMap<String, String>();
+		options.put("Store Secret Key for " + sender, "AuthAddSecretKey " + sender + "PersonalKeyShare " + colleagueTwoShare);
+		mail = new MailEntry(time, sender, colleagueTwo, topic, message, options);
+		Mail.sendMail(mail, colleagueTwo);
+		
+		MessageBay.displayMessage("PW Colleagues Set");
+	}
+
+	public static void emailPasswordShare(String colleagueName) {
+		Path credentialsDirectoryPath = Paths.get(FrameIO.CONTACTS_PATH).resolve(colleagueName + "-credentials");
+		String colleagueEmail = null;
+		try (Scanner in = new Scanner(credentialsDirectoryPath.resolve("credentials.inf").toFile())) {
+			int parseInt = Integer.parseInt(in.nextLine().replace(".exp", ""));
+			Frame frame = FrameIO.LoadFrame(colleagueName + "-credentials" + parseInt, credentialsDirectoryPath.toAbsolutePath().getParent().toString() + File.separator);
+			Collection<Text> textItems = frame.getTextItems();
+			textItems.removeIf(text -> !text.getText().startsWith("Email:"));
+			colleagueEmail = textItems.iterator().next().getText().replace("Email:", "").trim();
+		} catch (FileNotFoundException e) {
+			MessageBay.errorMessage("You do not appear to have contact with: " + colleagueName);
+			return;
+		}
+		
+		Frame secretsFrame = FrameIO.LoadFrame(UserSettings.UserName.get() + AuthenticatorBrowser.SECRETS_FRAME);
+		Collection<Text> textItems = secretsFrame.getTextItems();
+		textItems.removeIf(text -> !text.getText().toLowerCase().equals(colleagueName + "personalkeyshare"));
+		String key = textItems.iterator().next().getData().get(0);
+		
+		String nl = System.getProperty("line.separator");
+		StringBuilder sb = new StringBuilder();
+		sb.append("In responce to your request for assistance regaining access to your Expeditee account, your colleague " + UserSettings.UserName.get() + " has provided you with the following key share:" + nl);
+		sb.append(key + nl);
+		
+		try {
+			sendEmail(colleagueEmail, sb);
+		} catch (MessagingException e) {
+			MessageBay.errorMessage("An error occured sending a email to your colleage " + colleagueName + " with the email " + colleagueEmail);
+		}
+	}
+
+	public static void regainAccountAccess(Map<AuthenticationTag, String> userData) {
+		// Store shares in map
+		Map<Integer, byte[]> contributingParts = new HashMap<Integer, byte[]>();
+		contributingParts.put(1, Base64.getDecoder().decode(userData.get(AuthenticationTag.PasswordSliceOne)));
+		contributingParts.put(2, Base64.getDecoder().decode(userData.get(AuthenticationTag.PasswordSliceTwo)));
+		
+		// initialise shamir
+		int totalShares = 2;
+		int requiredShares = 2;
+		Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares);
+		
+		// perform joining
+		byte[] join = scheme.join(contributingParts);
+		
+		try {
+			AuthenticatorBrowser.getInstance().putKey(userData.get(AuthenticationTag.Username), userData.get(AuthenticationTag.NewPassword), new SecretKeySpec(join, SymmetricAlgorithm));
+		} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | ClassNotFoundException
+				| IOException | SQLException e) {
+			e.printStackTrace();
+		}
+		
+		MessageBay.displayMessage("Your new password has been set.");
 	}
 }
Index: trunk/src/org/expeditee/auth/mail/Mail.java
===================================================================
--- trunk/src/org/expeditee/auth/mail/Mail.java	(revision 1363)
+++ trunk/src/org/expeditee/auth/mail/Mail.java	(revision 1363)
@@ -0,0 +1,400 @@
+package org.expeditee.auth.mail;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.spec.InvalidKeySpecException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.expeditee.auth.AuthenticatorBrowser;
+import org.expeditee.auth.mail.gui.MailBay;
+import org.expeditee.encryption.Actions;
+import org.expeditee.gui.FrameIO;
+import org.expeditee.settings.UserSettings;
+import org.ngikm.cryptography.CryptographyConstants;
+
+public class Mail implements CryptographyConstants {
+	
+	private static List<MailEntry> messages = new ArrayList<MailEntry>();
+	
+	/**
+	 * Add a piece of mail, used during initialisation.
+	 */
+	public static void addEntry(MailEntry mail) {
+		messages.add(mail);
+	}
+	
+	public static void clear() {
+		messages.clear();
+	}
+	
+	public static void sendOneOffMail(MailEntry mail, String colleagueName, byte[] key) {
+		// Ensure dead drop area is set up.
+		Path databaseFileDirPath = ensureDeadDrops(colleagueName, mail.sender);
+		
+		// Ensure the database file exists.
+		Path databaseFilePath = ensureDatabaseFile(colleagueName, databaseFileDirPath);
+		
+		// Create secret key.
+		SecretKey secretKey = new SecretKeySpec(key, SymmetricAlgorithm);
+		
+		// Send message
+		sendMail(mail, secretKey, databaseFilePath);
+	}
+	
+	public static void sendMail(MailEntry mail, String colleagueName) {
+		// Ensure dead drop area is set up.
+		Path databaseFileDirPath = ensureDeadDrops(colleagueName);
+		
+		// Ensure the database file exists.
+		Path databaseFilePath = ensureDatabaseFile(colleagueName, databaseFileDirPath);
+		
+		// Obtain public key
+		PublicKey publicKey = null;
+		try {
+			publicKey = AuthenticatorBrowser.getInstance().getPublicKey(colleagueName);
+		} catch (InvalidKeySpecException | NoSuchAlgorithmException | KeyStoreException | CertificateException
+				| ClassNotFoundException | IOException | SQLException e) {
+			System.err.println("Error while sending message.  Unable to obtain public key for colleague " +  
+				colleagueName + ".  Exception message: " + e.getMessage());
+			return;
+		}
+		
+		// Check we got public key
+		if (publicKey == null) {
+			System.err.println("Error while sending message.  Unable to obtain public key for colleague.  Have you exchanged contact details?");
+			return;
+		}
+		
+		// Send message
+		sendMail(mail, publicKey, databaseFilePath);
+	}
+
+	private static Path ensureDatabaseFile(String colleagueName, Path databaseFileDirPath) {
+		Path databaseFilePath = databaseFileDirPath.resolve(colleagueName + ".db");
+		File databaseFile = databaseFilePath.toFile();
+		if (!databaseFile.exists()) {
+			databaseFileDirPath.toFile().mkdirs();
+			String sql = 
+					"CREATE TABLE EXPMAIL (" +
+					"TIME		TEXT					NOT NULL, " +
+					"SND		TEXT					NOT NULL, " + 
+					"REC		TEXT					NOT NULL, " + 
+					"MSG		TEXT					NOT NULL, " +
+					"MSG2		TEXT					NOT NULL, " + 
+					"OPTS		ARRAY					NOT NULL, " +
+					"OPTSVAL	ARRAY					NOT NULL)";
+			try {
+				Connection c = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getAbsolutePath());
+				Statement createTable = c.createStatement();
+				createTable.executeUpdate(sql);
+				createTable.close();
+				c.close();
+			} catch (SQLException e) {
+				System.err.println("Error while creating database file.");
+				e.printStackTrace();
+			}
+		}
+		return databaseFilePath;
+	}
+
+	private static Path ensureDeadDrops(String colleagueName) {
+		String me = UserSettings.UserName.get().toLowerCase();
+		String them = colleagueName.toLowerCase();
+		Path databaseFileDirPath = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(me + "+" + them);
+		if (!databaseFileDirPath.toFile().exists()) {
+			databaseFileDirPath = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(them + "+" + me);
+		}
+		return databaseFileDirPath;
+	}
+	
+	private static Path ensureDeadDrops(String colleagueName, String sender) {
+		String me = sender.toLowerCase();
+		String them = colleagueName.toLowerCase();
+		Path parent = Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-" + sender).resolve("deaddrops");
+		Path databaseFileDirPath = parent.resolve(me + "+" + them);
+		if (!databaseFileDirPath.toFile().exists()) {
+			databaseFileDirPath = parent.resolve(them + "+" + me);
+		}
+		return databaseFileDirPath;
+	}
+	
+	private static void sendMail(MailEntry mail, PublicKey key, Path databaseFile) {
+		try {
+			Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String sender = Base64.getEncoder().encodeToString(cipher.doFinal(mail.sender.getBytes()));
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String rec = Base64.getEncoder().encodeToString(cipher.doFinal(mail.receiver.getBytes()));
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String message = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message.getBytes()));
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String message2 = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message2.getBytes()));
+			
+			Map<String, String> options = new HashMap<String, String>(); 
+			for (String label: mail.options.keySet()) {
+				cipher.init(Cipher.ENCRYPT_MODE, key);
+				String labelEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(label.getBytes()));
+				cipher.init(Cipher.ENCRYPT_MODE, key);
+				String actionNameEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(mail.options.get(label).getBytes()));
+				options.put(labelEncrypted, actionNameEncrypted);
+			}
+			
+			// write to mail database
+			writeToMailDatabase(mail, databaseFile, sender, rec, message, message2, options);			
+		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | SQLException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private static void sendMail(MailEntry mail, SecretKey key, Path databaseFile) {
+		try {
+			//	Encrypt message.
+			Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String sender = "=" + Base64.getEncoder().encodeToString(cipher.doFinal(mail.sender.getBytes()));
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String rec = Base64.getEncoder().encodeToString(cipher.doFinal(mail.receiver.getBytes()));
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String message = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message.getBytes()));
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			String message2 = Base64.getEncoder().encodeToString(cipher.doFinal(mail.message2.getBytes()));			
+			Map<String, String> options = new HashMap<String, String>(); 
+			for (String label: mail.options.keySet()) {
+				cipher.init(Cipher.ENCRYPT_MODE, key);
+				String labelEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(label.getBytes()));
+				cipher.init(Cipher.ENCRYPT_MODE, key);
+				String actionNameEncrypted = Base64.getEncoder().encodeToString(cipher.doFinal(mail.options.get(label).getBytes()));
+				options.put(labelEncrypted, actionNameEncrypted);
+			}
+			
+			//	Write to mail database.
+			writeToMailDatabase(mail, databaseFile, sender, rec, message, message2, options);
+		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | SQLException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static void writeToMailDatabase(MailEntry mail, Path databaseFile, String sender, String rec,
+			String message, String message2, Map<String, String> options) throws SQLException {
+		Connection c = DriverManager.getConnection("jdbc:sqlite:" + databaseFile);
+		String sql = "INSERT INTO EXPMAIL (TIME,SND,REC,MSG,MSG2,OPTS,OPTSVAL) VALUES (?, ?, ?, ?, ?, ?, ?);";
+		PreparedStatement statement = c.prepareStatement(sql);
+		statement.setString(1, mail.timestamp);
+		statement.setString(2, sender);
+		statement.setString(3, rec);
+		statement.setString(4, message);
+		statement.setString(5, message2);
+		String opts = Arrays.toString(options.keySet().toArray());
+		statement.setString(6, opts);
+		String optsval = Arrays.toString(options.values().toArray());
+		statement.setString(7, optsval);
+		statement.execute();
+		statement.close();
+		c.close();
+		System.err.println("Message written to database: " + databaseFile.toString());
+	}
+		
+	/**
+	 * Gets the mail messages that the specified user is able to read.
+	 * The caller supplies their username and private key.  
+	 * If the private key can decrypt a message, then it was encrypted using the users public key, and is therefore for them.
+	 */
+	private static List<MailEntry> getEntries(String name, PrivateKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
+		List<MailEntry> filtered = new ArrayList<MailEntry>();
+		
+		for (MailEntry mail: messages) {
+			if (isEncryptedOneOffMessage(mail)) {
+				getOneOffSecureMail(name, filtered, mail);
+			} else {
+				getStandardSecureMail(name, key, filtered, mail);
+			}
+		}
+		
+		return filtered;
+	}
+
+	private static void getOneOffSecureMail(String name, List<MailEntry> filtered, MailEntry mail) {
+		StringBuilder sb = new StringBuilder();
+		String sep = ":::";
+		sb.append("Read one-off secure message." + sep);
+		sb.append(mail.timestamp + sep);
+		sb.append(mail.sender.substring(1) + sep);
+		sb.append(mail.receiver + sep);
+		sb.append(mail.message + sep);
+		sb.append(mail.message2 + sep);
+		for (String k: mail.options.keySet()) {
+			sb.append(k + sep + mail.options.get(k) + sep);
+		}
+		sb.reverse().delete(0, 3).reverse();
+		Map<String, String> options = new HashMap<String, String>();
+		options.put(sb.toString(), "AuthOneOffSecureMessage");
+		String currentTime = org.expeditee.stats.Formatter.getDateTime();
+		MailEntry mailOuter = new MailEntry(currentTime, "Unknown", name, "You have received a one-off secure message.", "Check your email for more details.", options);
+		
+		if (mail.deadDropSource != null) {
+			Path lastAccessedFile = mail.deadDropSource.getParent().resolve(name + ".last-accessed");
+			SimpleDateFormat format = new SimpleDateFormat("ddMMMyyyy[HH:mm]");
+			try (Scanner in = new Scanner(lastAccessedFile.toFile())) {
+				Date lastAccessedTimestamp = format.parse(in.nextLine());
+				Date mailTimestamp = format.parse(mail.timestamp);
+				if (mailTimestamp.after(lastAccessedTimestamp)) {
+					filtered.add(mailOuter);
+				}
+			} catch (FileNotFoundException e) {
+				// It may not have been created yet, then err on the safe side and add it in.
+				filtered.add(mailOuter);
+			} catch (ParseException e) {
+				// If we fail to parse, then err on the safe side and add it in.
+				filtered.add(mailOuter);
+			}
+		}
+	}
+
+	private static void getStandardSecureMail(String name, PrivateKey key, List<MailEntry> filtered, MailEntry mail)
+			throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, InvalidKeyException,
+			BadPaddingException {
+		// confirm this is a message for the requester of entries
+		String receiver = mail.receiver;
+		byte[] receiverBytes = Base64.getDecoder().decode(receiver);
+		String receiverDecrypted = null;
+		Cipher c = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
+		try {
+			c.init(Cipher.DECRYPT_MODE, key);
+			receiverDecrypted = new String(c.doFinal(receiverBytes));
+		} catch (InvalidKeyException | BadPaddingException e) {
+			return;
+		}
+		
+		// add an unencrypted version of the message to the return list
+		if (receiverDecrypted.compareToIgnoreCase(name) == 0) {
+			c.init(Cipher.DECRYPT_MODE, key);
+			String sender = new String(c.doFinal(Base64.getDecoder().decode(mail.sender)));
+			c.init(Cipher.DECRYPT_MODE, key);
+			String message = new String(c.doFinal(Base64.getDecoder().decode(mail.message)));
+			c.init(Cipher.DECRYPT_MODE, key);
+			String message2 = new String(c.doFinal(Base64.getDecoder().decode(mail.message2)));
+			
+			Map<String, String> options = new HashMap<String, String>();
+			for (String label: mail.options.keySet()) {
+				c.init(Cipher.DECRYPT_MODE, key);
+				String labelDecrypted = new String(c.doFinal(Base64.getDecoder().decode(label)));
+				c.init(Cipher.DECRYPT_MODE, key);
+				String actionNameDecrypted = new String(c.doFinal(Base64.getDecoder().decode(mail.options.get(label))));
+				options.put(labelDecrypted, actionNameDecrypted);
+			}
+			
+			Path lastAccessedFile = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(UserSettings.UserName.get() + "+" + sender).resolve(name + ".last-accessed");
+			if (!lastAccessedFile.toFile().exists()) {
+				lastAccessedFile = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(sender + "+" + UserSettings.UserName.get()).resolve(name + ".last-accessed");
+			}
+			SimpleDateFormat format = new SimpleDateFormat("ddMMMyyyy[HH:mm]");
+			MailEntry mailEntry = new MailEntry(mail.timestamp, sender, receiverDecrypted, message, message2, options);
+			try (Scanner in = new Scanner(lastAccessedFile.toFile())) {
+				Date lastAccessedTimestamp = format.parse(in.nextLine());
+				Date mailTimestamp = format.parse(mail.timestamp);
+				if (mailTimestamp.after(lastAccessedTimestamp)) {
+					filtered.add(mailEntry);
+				}
+			} catch (FileNotFoundException e) {
+				// It may not have been created yet, then err on the safe side and add it in.
+				filtered.add(mailEntry);
+			} catch (ParseException e) {
+				// If we fail to parse, then err on the safe side and add it in.
+				filtered.add(mailEntry);
+			}			
+			
+		}
+	}
+	
+	private static boolean isEncryptedOneOffMessage(MailEntry mail) {
+		return mail.sender.charAt(0) == '=';
+	}
+	
+	/**
+	 * Describes a piece of mail, either encrypted or decrypted.
+	 */
+	public static class MailEntry {
+		public String timestamp;
+		public String sender;
+		public String receiver;
+		public String message;
+		public String message2;
+		public Map<String, String> options;
+		public Path deadDropSource;
+		
+		public MailEntry(String timestamp, String sender, String rec, String message, String message2, Map<String, String> options) {
+			this.timestamp = timestamp;
+			this.sender = sender;
+			this.receiver = rec;
+			this.message = message;
+			this.message2 = message2;
+			this.options = options;
+		}
+	}
+
+	public static void checkMail(PrivateKey key) throws NoSuchAlgorithmException, NoSuchPaddingException,
+			IllegalBlockSizeException, BadPaddingException, InvalidKeyException, KeyStoreException,
+			FileNotFoundException, CertificateException, IOException, ClassNotFoundException, SQLException, ParseException {
+		MailBay.clear();
+		AuthenticatorBrowser.getInstance().loadMailDatabase();
+		List<MailEntry> mailForLoggingInUser = Mail.getEntries(UserSettings.UserName.get(), key);			
+		for (MailEntry mail: mailForLoggingInUser) {
+			MailBay.addMessage(mail.timestamp, mail.message, mail.message2, mail.options);
+		}
+		
+		// Update last read files.
+		Path deadDropPath = Paths.get(FrameIO.DEAD_DROPS_PATH);
+		for (File connectionDir: deadDropPath.toFile().listFiles()) {
+			if (connectionDir.isDirectory()) {
+				Path deaddropforcontactPath = Paths.get(connectionDir.getAbsolutePath());
+				AuthenticatorBrowser.getInstance().updateLastReadMailTime(deaddropforcontactPath);
+			}
+		}
+	}
+
+	public static void decryptOneOffSecureMessage(SecretKey key, List<String> data) {
+		byte[] topicBytes = Base64.getDecoder().decode(data.get(3));
+		String topic = new String(org.expeditee.encryption.Actions.DecryptSymmetric(topicBytes, key));
+		byte[] messageBytes = Base64.getDecoder().decode(data.get(4));
+		String message = new String(org.expeditee.encryption.Actions.DecryptSymmetric(messageBytes, key));
+		Map<String, String> options = new HashMap<String, String>();
+		for (int i = 5; i < data.size(); i+=2) {
+			byte[] optionKeyBytes = Base64.getDecoder().decode(data.get(i));
+			String k = new String(org.expeditee.encryption.Actions.DecryptSymmetric(optionKeyBytes, key));
+			byte[] optionValueBytes = Base64.getDecoder().decode(data.get(i + 1));
+			String v = new String(org.expeditee.encryption.Actions.DecryptSymmetric(optionValueBytes, key));
+			options.put(k, v);
+		}
+		MailBay.addMessage(data.get(0), topic, message, options);
+	}
+}
Index: trunk/src/org/expeditee/auth/mail/gui/MailBay.java
===================================================================
--- trunk/src/org/expeditee/auth/mail/gui/MailBay.java	(revision 1363)
+++ trunk/src/org/expeditee/auth/mail/gui/MailBay.java	(revision 1363)
@@ -0,0 +1,317 @@
+package org.expeditee.auth.mail.gui;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.expeditee.auth.AuthenticatorBrowser;
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Font;
+import org.expeditee.core.Image;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.FrameCreator;
+import org.expeditee.gui.FrameGraphics;
+import org.expeditee.gui.FrameIO;
+import org.expeditee.gui.MessageBay;
+import org.expeditee.items.Item;
+import org.expeditee.items.Text;
+import org.expeditee.settings.UserSettings;
+
+public class MailBay {
+	public static final String EXPEDITEE_MAIL_FRAMESET_NAME = "expediteemail";
+
+	/** The y position of the header to the mail bay. */
+	private static final int HEADER_OFFSET_Y = 15;
+	
+	/** Space between mail messages */
+	private static final int SPACING = 25;
+	
+	/** The (x,y) of the top message. */
+	private static final int MESSAGE_OFFSET_Y = 15 + SPACING;
+	private static final int OFFSET_X = 20;
+
+	/** Buffer image of the mail window. */
+	private static Image _mailBuffer;
+	
+	/** The list of messages shown in the mail bay. */
+	private static List<Item> _previewMessages = new LinkedList<Item>();
+	private static List<Item> _messages = new LinkedList<Item>();
+	
+	/** Font used for mail messages. */
+	private static Font _messageFont = new Font("Serif-Plain-16");
+
+	/** Used to number messages. */
+	private static int _messageCount;
+	
+	/** Creator for creating the mail frames. */
+	private static FrameCreator _creator = null;
+	
+	/** The currently logged in user, consulted when deciding if a new FrameCreator is needed. */
+	private static String _forUser = UserSettings.UserName.get();
+	
+	/** The link that the preview pane displays pointing towards unprocessed messages. */
+	private static Text _mailLink = new Text(-2, "@Mail", Colour.BLACK, Colour.WHITE);
+
+	/** Wether the link has been drawn before. */
+	private static boolean isLinkInitialized = false;
+
+	/** The position of the mail link. */
+	private static int MAIL_LINK_Y_OFFSET = 100;
+	private static int MAIL_LINK_X = 50;
+	
+	/**
+	 * Obtain the two messages shown at the bottom of the screen as a preview to the entire collection of mail.
+	 * @return
+	 */
+	public static List<Item> getPreviewMessages() {
+		return _previewMessages;
+	}
+	
+	/**
+	 * An item is a 'preview mail item' if it is currently being previewed at the bottom of the screen.
+	 * @param i
+	 * @return
+	 */
+	public static boolean isPreviewMailItem(Item i) {
+		return _previewMessages.contains(i) || i == _mailLink;
+	}
+	
+	public static void disconnect() {
+		if (_forUser != UserSettings.UserName.get()) {
+			_creator = null;
+			_forUser = UserSettings.UserName.get();
+		}
+	}
+		
+	/**
+	 * Adds a message to the MailBay.
+	 * @param message The basic text of the message, what is displayed in the bay window down the bottom.
+	 * @options A map describing the buttons to be provided as reply options (Button Text, Action to run)
+	 * @return
+	 */
+	public synchronized static Text addMessage(String timestamp, String message, String message2, Map<String, String> options) {
+		// Invalidate whole area
+		DisplayController.invalidateArea(DisplayController.getMessageBayPaintArea());
+		
+		// Ensure frame creator
+		if (_creator == null || _forUser != UserSettings.UserName.get()) {
+			_forUser = UserSettings.UserName.get();
+			_creator = new FrameCreator(EXPEDITEE_MAIL_FRAMESET_NAME, FrameIO.MAIL_PATH, EXPEDITEE_MAIL_FRAMESET_NAME, FrameCreator.ExistingFramesetOptions.AppendAfterLastItem, false, AuthenticatorBrowser.PROFILEENCRYPTIONLABEL);
+		}
+				
+		// We have enough space for the header + 2 preview messages
+		if (_previewMessages.size() >= 2) {
+			_previewMessages.remove(0);
+			for (Item i : _previewMessages) {
+				i.setY(i.getY() - SPACING);
+			}
+		}
+		
+		// Add new message
+		Mail mail = new Mail(message, message2, options);
+		Text t = mail.getPreviewMessage(true);
+		_messages.add(t);
+		_creator.addText(timestamp, Colour.BLACK, null, null, false);
+		for (Text line: mail.getMessage()) {
+			_creator.addItem(line.copy(), false);
+		}
+		t.setLink(_creator.getCurrentFrame().getName());
+		_previewMessages.add(t);
+		_creator.addSpace(SPACING);
+		_creator.save();
+		
+		// Make sure the link points to the latest frame
+		_mailLink.setLink(_creator.getCurrent());
+		
+		DisplayController.requestRefresh(true);
+		
+		return t;
+	}
+
+	/**
+	 * Obtains the image item that is drawn to display the mail bay.
+	 * @param clip
+	 * @param size
+	 * @return
+	 */
+	public static Image getImage(Clip clip, Dimension size) {
+		// Can't get an image with an invalid size
+		if (size == null || size.width <= 0 || size.height <= 0) {
+			return null;
+		}
+		
+		// Update the buffer
+		updateBuffer(Item.DEFAULT_BACKGROUND, clip, size);
+		
+		// Return the image buffer
+		return _mailBuffer;
+	}
+	
+	public static void clear() {
+		getPreviewMessages().clear();
+		_messageCount = 0;
+	}
+	
+	public static Item getMailLink() {
+		return _mailLink;
+	}
+	
+	public static void ensureLink() {
+		if (_mailLink.getLink() == null && FrameIO.canAccessFrame(MailBay.EXPEDITEE_MAIL_FRAMESET_NAME + 1)) {
+			_mailLink.setLink(MailBay.EXPEDITEE_MAIL_FRAMESET_NAME + 1);
+		}
+	}	
+	
+	/** Updates the image buffer to reflect the current state of the mail bay. */
+	private synchronized static void updateBuffer(Colour background, Clip clip, Dimension size) {
+		// If the buffer doesn't exist or is the wrong size, recreate it
+		if (_mailBuffer == null || !_mailBuffer.getSize().equals(size)) {
+			_mailBuffer = Image.createImage(size, true);
+			clip = null; // Need to recreate the entire image;
+			updateSize();
+		}
+		
+		// Prepare graphics
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		g.pushDrawingSurface(_mailBuffer);
+		if (clip != null) {
+			g.pushClip(clip);
+		}
+		g.setAntialiasing(true);
+		g.clear(background);
+		g.setFont(_messageFont);
+		
+		// Paint header
+		FrameGraphics.PaintItem(getHeader(Colour.BLACK));
+		
+		// Paint the mail messages to the screen (preview)
+		for (Item message : _previewMessages) {
+			if (message != null) {
+				if (clip == null || clip.isNotClipped() || message.isInDrawingArea(clip.getBounds())) {
+					FrameGraphics.PaintItem(message);
+				}
+			}
+		}
+		
+		// Paint the status from the MessageBay
+		Item status = MessageBay.getStatus();
+		if (status != null) {
+			FrameGraphics.PaintItem(status);
+		}
+		
+		// Paint the link to the mail frame
+		if (clip == null || clip.isNotClipped() || _mailLink.isInDrawingArea(clip.getBounds())) {
+			FrameGraphics.PaintItem(_mailLink);
+		}
+		
+		g.popDrawingSurface();
+	}
+	
+	/** Syncs message bay size according to FrameGraphics max size. */
+	private static void updateSize() {
+		for (Item i : _previewMessages) {
+			if (i != null) {
+				i.setOffset(0, -DisplayController.getMessageBayPaintArea().getMinY());
+			}
+		}
+		
+		_mailLink.setOffset(0, -DisplayController.getMessageBayPaintArea().getMinY());
+		updateLink();
+	}
+	
+	private static void updateLink() {
+		if (!isLinkInitialized && DisplayController.getFramePaintArea() != null
+				&& DisplayController.getFramePaintAreaWidth() > 0) {
+			// set up 'Messages' link on the right hand side
+			_mailLink.setPosition(DisplayController.getMessageBayPaintArea().getWidth() - MAIL_LINK_Y_OFFSET,
+					MAIL_LINK_X);
+			_mailLink.setOffset(0, -DisplayController.getMessageBayPaintArea().getMinY());
+			isLinkInitialized = true;
+		} else {
+			_mailLink.setPosition(DisplayController.getMessageBayPaintArea().getWidth() - MAIL_LINK_Y_OFFSET,
+					MAIL_LINK_X);
+		}
+	}
+
+	private static Text getHeader(Colour fontColor) {
+		Text t = new Text("You have [" + _messages.size() + "] unprocessed messages waiting.");
+		if (_messages.size() >= 2) {
+			t.setText(t.getText() + "  Two latest below:");
+		}
+		t.setPosition(OFFSET_X, HEADER_OFFSET_Y);
+		t.setOffset(0, -DisplayController.getFramePaintAreaHeight());
+		t.setColor(fontColor);
+		t.setFont(_messageFont.clone());
+		return t;
+	}
+	
+	private static String getMessagePrefix() {
+		_messageCount++;
+		return "@" + _messageCount + ": ";
+	}
+	
+	private static class Mail {
+		private String message;
+		private Map<String, String> options;
+		private String message2;
+
+		private Mail(String message, String message2, Map<String, String> options) {
+			this.message = message;
+			this.message2 = message2;
+			this.options = options;
+		}
+		
+		private Text getPreviewMessage(boolean usePrefix) {
+			Text t = usePrefix ? new Text(getMessagePrefix() + message)	: new Text(message);
+			int y = MESSAGE_OFFSET_Y + _previewMessages.size() * SPACING;
+			t.setPosition(OFFSET_X, y);
+			t.setColor(Colour.BLACK);
+			t.setFont(_messageFont.clone());
+			return t;
+		}
+		
+		private Text getDetailLine() {
+			if (message2 == null || message2.isEmpty()) { 
+				return null;
+			}
+			Text t = new Text(message2);
+			int y = MESSAGE_OFFSET_Y + _previewMessages.size() * SPACING;
+			t.setPosition(OFFSET_X, y);
+			t.setColor(Colour.BLACK);
+			t.setFont(_messageFont.clone());
+			return t;
+		}
+		
+		private Text[] getMessage() {
+			List<Text> items = new LinkedList<Text>();
+			items.add(getPreviewMessage(false));
+			Text detail = getDetailLine();
+			if (detail != null) {
+				items.add(detail);
+			}
+			
+			int i = items.size();
+			for (String content: options.keySet()) {
+				String[] split = content.split(":::");
+				String action = options.get(content);
+				Text t = new Text(split[0]);
+				for (int o = 1; o < split.length; o++) {
+					t.addToData(split[o]);
+				}
+				int y = MESSAGE_OFFSET_Y + (_previewMessages.size() + i) * SPACING;
+				t.setPosition(OFFSET_X, y);
+				t.setColor(Colour.BLUE);
+				t.setFont(_messageFont.clone());
+				t.setAction(action);
+				items.add(t);
+				i++;
+			}
+			
+			return items.toArray(new Text[] {});
+		}
+	}
+}
Index: trunk/src/org/expeditee/auth/tags/AuthenticationTag.java
===================================================================
--- trunk/src/org/expeditee/auth/tags/AuthenticationTag.java	(revision 1362)
+++ trunk/src/org/expeditee/auth/tags/AuthenticationTag.java	(revision 1363)
@@ -19,5 +19,7 @@
 	ColleagueTwo ("txtColleagueTwo", System.getProperty("user.colleague.two")), 
 	Frameset ("txtFrameset", System.getProperty("user.toshare.frameset")), 
-	IntergalacticNumber ("txtIntergalacticNumber", System.getProperty("user.intergalacticnumber")); 
+	IntergalacticNumber ("txtIntergalacticNumber", System.getProperty("user.intergalacticnumber")), 
+	PasswordSliceOne ("txtPasswordPieceOne", System.getProperty("user.password.piece.one")), 
+	PasswordSliceTwo ("txtPasswordPieceTwo", System.getProperty("user.password.piece.two")); 
 	
 	public String val;
Index: trunk/src/org/expeditee/encryption/Actions.java
===================================================================
--- trunk/src/org/expeditee/encryption/Actions.java	(revision 1363)
+++ trunk/src/org/expeditee/encryption/Actions.java	(revision 1363)
@@ -0,0 +1,199 @@
+package org.expeditee.encryption;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.expeditee.auth.AuthenticatorBrowser;
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.Frame;
+import org.expeditee.gui.FrameIO;
+import org.expeditee.items.Text;
+import org.expeditee.settings.UserSettings;
+import org.ngikm.cryptography.CryptographyConstants;
+
+import com.codahale.shamir.Scheme;
+
+public class Actions implements CryptographyConstants {
+	
+	public static Text GenerateSecret(String label) {
+		return AuthGenerateSecret(label);
+	}
+	
+	public static Text SplitSecret(Text key) {
+		return AuthSplitSecret(key);
+	}
+	
+	public static Text JoinSecret(Text key) {
+		return AuthJoinSecret(key);
+	}
+	
+	public static void Encrypt(Text labelWithKey) {
+		AuthEncrypt(labelWithKey);
+	}
+	
+	public static void Decrypt(Text labelWithKey) {
+		AuthDecrypt(labelWithKey);
+	}
+	
+	public static Text AuthGenerateSecret(String label) {
+		// Generate AES Key
+		Random rand = new SecureRandom();
+		byte[] keyBytes = new byte[16];
+		rand.nextBytes(keyBytes);
+		String key = Base64.getEncoder().encodeToString(keyBytes);
+		
+		Text text = new Text(label);
+		text.setData(key);
+		text.setPosition(DisplayController.getMousePosition());
+		return text;
+	}
+
+	public static Text AuthSplitSecret(Text key) {
+		// Retrieve secret
+		String secret = key.getData().get(0);
+		byte[] secretBytes = Base64.getDecoder().decode(secret);
+		
+		// Obtain parameters for shamir
+		String[] arguments = key.getText().split(" ");
+		int requiredShares = Integer.parseInt(arguments[1]);
+		int totalShares = arguments.length - 2;
+		
+		// Create shares
+		Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares);
+		Map<Integer, byte[]> split = scheme.split(secretBytes);
+		
+		// Add shares to key
+		List<String> data = key.getData();
+		for (Integer i: split.keySet()) {
+			data.add("{" + i + "}" + Base64.getEncoder().encodeToString(split.get(i)));
+		}
+		key.setData(data);
+		
+		return key;
+	}
+	
+	public static Text AuthJoinSecret(Text key) {
+		Map<Integer, byte[]> contributingParts = new HashMap<Integer, byte[]>();
+		
+		// Retrieve splits
+		List<String> data = key.getData();
+		for (String d: data) {
+			if (d.startsWith("{")) {
+				String[] split = d.split("}");
+				Integer k = Integer.parseInt(split[0].replace("{", ""));
+				byte[] v = Base64.getDecoder().decode(split[1]);
+				contributingParts.put(k, v);
+			}
+		}
+		
+		// Obtain parameters for shamir
+		String[] arguments = key.getText().split(" ");
+		int totalShares = Integer.parseInt(arguments[2]);
+		int requiredShares = Integer.parseInt(arguments[1]);
+		
+		// Perform join
+		Scheme scheme = new Scheme(new SecureRandom(), totalShares, requiredShares);
+		byte[] join = scheme.join(contributingParts);
+		
+		data.clear();
+		data.add(Base64.getEncoder().encodeToString(join));
+		
+		return key;
+	}
+	
+	public static void AuthEncrypt(Text labelWithKey) {
+		// Obtain encryption key
+		String keyEncoded = labelWithKey.getData().get(0);
+		byte[] keyDecoded = Base64.getDecoder().decode(keyEncoded);
+		SecretKey key = new SecretKeySpec(keyDecoded, SymmetricAlgorithm);
+		
+		// Perform encryption
+		Frame toEncrypt = FrameIO.LoadFrame(labelWithKey.getLink());
+		Collection<Text> textItems = toEncrypt.getTextItems();
+		for (Text t: textItems) {
+			byte[] encrypted = EncryptSymmetric(t.getText().getBytes(), key);
+			t.setText(Base64.getEncoder().encodeToString(encrypted));
+		}
+		
+		// Save changes
+		FrameIO.SaveFrame(toEncrypt);
+	}
+	
+	public static void AuthDecrypt(Text labelWithKey) {
+		// Obtain encryption key
+		String keyEncoded = labelWithKey.getData().get(0);
+		byte[] keyDecoded = Base64.getDecoder().decode(keyEncoded);
+		SecretKey key = new SecretKeySpec(keyDecoded, SymmetricAlgorithm);
+		
+		// Perform decryption
+		Frame toDecrypt = FrameIO.LoadFrame(labelWithKey.getLink());
+		Collection<Text> textItems = toDecrypt.getTextItems();
+		for (Text t: textItems) {
+			byte[] decrypted = DecryptSymmetric(Base64.getDecoder().decode(t.getText().getBytes()), key);
+			t.setText(new String(decrypted));
+		}
+		
+		// Save changes
+		FrameIO.SaveFrame(toDecrypt);
+	}
+	
+	public static byte[] EncryptSymmetric(final byte[] toEncrypt, final SecretKey key) {
+		// toEncrypt = Base64.getDecoder().decode(toEncrypt);
+		try {
+			final Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
+			cipher.init(Cipher.ENCRYPT_MODE, key);
+			//could use modulus
+			final int length = (int) ((Math.ceil(toEncrypt.length / 16f)) * 16);
+			final byte[] toEncryptSizeAdjusted = Arrays.copyOf(toEncrypt, length);
+			//System.err.println("(" + toEncryptSizeAdjusted.length + ")" + "Before Encryption Data: "
+			//		+ Arrays.toString(toEncryptSizeAdjusted));
+			final byte[] result = cipher.doFinal(toEncryptSizeAdjusted);
+			//System.err.println("(" + result.length + ")" + "Encrypted Data: " + Arrays.toString(result));
+			return result;
+		} catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
+				| IllegalBlockSizeException | BadPaddingException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	public static byte[] DecryptSymmetric(final byte[] toDecrypt, final SecretKey key) {
+		try {
+			final Cipher cipher = Cipher.getInstance(SymmetricAlgorithm + SymmetricAlgorithmParameters);
+			cipher.init(Cipher.DECRYPT_MODE, key);
+			final byte[] decryptedBytes = cipher.doFinal(toDecrypt);
+			int indexOfZero = decryptedBytes.length - 1;
+			for (int i = decryptedBytes.length - 1; i >= 0; i--) {
+				if (decryptedBytes[i] != (byte) 0) {
+					indexOfZero = i + 1;
+					break;
+				}
+			}
+			return Arrays.copyOf(decryptedBytes, indexOfZero);
+		} catch (final NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
+				| IllegalBlockSizeException | BadPaddingException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	public static void AuthAddSecretKey(String name, String data) {
+		Frame secretsFrame = FrameIO.LoadFrame(UserSettings.UserName.get() + AuthenticatorBrowser.SECRETS_FRAME);
+		secretsFrame.addText(500, 500, name, null).addToData(data);
+	}
+}
Index: trunk/src/org/expeditee/gui/DisplayController.java
===================================================================
--- trunk/src/org/expeditee/gui/DisplayController.java	(revision 1362)
+++ trunk/src/org/expeditee/gui/DisplayController.java	(revision 1363)
@@ -28,5 +28,5 @@
 import java.util.function.BooleanSupplier;
 
-import org.expeditee.auth.gui.MailBay;
+import org.expeditee.auth.mail.gui.MailBay;
 import org.expeditee.core.Clip;
 import org.expeditee.core.Colour;
Index: trunk/src/org/expeditee/gui/FrameIO.java
===================================================================
--- trunk/src/org/expeditee/gui/FrameIO.java	(revision 1362)
+++ trunk/src/org/expeditee/gui/FrameIO.java	(revision 1363)
@@ -55,5 +55,5 @@
 import org.expeditee.auth.EncryptedExpReader;
 import org.expeditee.auth.EncryptedExpWriter;
-import org.expeditee.auth.gui.MailBay;
+import org.expeditee.auth.mail.gui.MailBay;
 import org.expeditee.gio.EcosystemManager;
 import org.expeditee.io.Conversion;
Index: trunk/src/org/expeditee/gui/FrameUtils.java
===================================================================
--- trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1362)
+++ trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1363)
@@ -55,5 +55,5 @@
 import org.expeditee.agents.InvalidFramesetNameException;
 import org.expeditee.auth.AuthenticatorBrowser;
-import org.expeditee.auth.gui.MailBay;
+import org.expeditee.auth.mail.gui.MailBay;
 import org.expeditee.core.Colour;
 import org.expeditee.core.Point;
Index: trunk/src/org/expeditee/settings/identity/passwordrecovery/Colleagues.java
===================================================================
--- trunk/src/org/expeditee/settings/identity/passwordrecovery/Colleagues.java	(revision 1362)
+++ trunk/src/org/expeditee/settings/identity/passwordrecovery/Colleagues.java	(revision 1363)
@@ -6,6 +6,3 @@
 	public static final StringSetting Colleague_One = new StringSetting("Your first password recovery colleague.", null);
 	public static final StringSetting Colleague_Two = new StringSetting("Your second password recovery colleague.", null);
-	
-	public static final StringSetting Colleague_One_Email = new StringSetting("Your first password recovery colleagues public facing email.", null);
-	public static final StringSetting Colleague_Two_Email = new StringSetting("Your second password recovery colleagues public facing email.", null);
 }
