Index: trunk/src/org/expeditee/encryption/io/EncryptedExpReader.java
===================================================================
--- trunk/src/org/expeditee/encryption/io/EncryptedExpReader.java	(revision 1414)
+++ trunk/src/org/expeditee/encryption/io/EncryptedExpReader.java	(revision 1415)
@@ -24,4 +24,5 @@
 import javax.crypto.spec.SecretKeySpec;
 
+import org.expeditee.core.Point;
 import org.expeditee.encryption.CryptographyConstants;
 import org.expeditee.encryption.items.surrogates.EncryptionDetail;
@@ -33,4 +34,5 @@
 import org.expeditee.io.DefaultFrameWriter;
 import org.expeditee.io.ExpReader;
+import org.expeditee.items.Constraint;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -44,9 +46,12 @@
 	private SecretKey personalKey;
 	private boolean accessDenied = false;
+	private boolean _readingSurrogates;
+	private static final Predicate<String> endOfSection = s -> s.equals(EncryptedExpWriter.TERMINATOR + "") || s.equals(EncryptedExpWriter.TERMINATOR_WITH_CONTINUATION);
 
 	public static boolean isEncryptedExpediteeFile(final String path) throws IOException {
-		final BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
-		final String firstLine = in.readLine();
+		BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
+		String firstLine = in.readLine();
 		in.close();
+		if (firstLine == null) return false;
 		return firstLine.startsWith(ENCRYPTED_EXP_FLAG);
 	}
@@ -87,4 +92,5 @@
 		if (accessDenied) { return null; }
 		
+		_readingSurrogates = false;
 		_reader = reader;
 		String next = "";
@@ -106,4 +112,11 @@
 			next = readTheConstraints();
 			
+			if (next.equals(EncryptedExpWriter.TERMINATOR_WITH_CONTINUATION)) {
+				// Read the surrogates
+				_readingSurrogates = true;
+				next = readTheItems(newFrame, delayedActions);
+				_readingSurrogates = false;
+			}
+			
 			for(DelayedAction action: delayedActions) {
 				action.exec();
@@ -124,54 +137,37 @@
 	}
 	
-//	@Override
-//	protected String readTheItems(Frame newFrame, List<DelayedAction> delayedActions) throws IOException {
-//		String next = null;
-//		Item currentItem = null;
-//		
-//		Predicate<String> endOfSection = s -> s.equals(EncryptedExpWriter.TERMINATOR + "") || s.equals(EncryptedExpWriter.TERMINATOR_WITH_CONTINUATION);
-//		while (_reader.ready() && !endOfSection.test(next = _reader.readLine())) {
-//			if (!isValidLine(next)) {
-//				continue;
-//			}
-//			
-//			String tag = getTagEnc(next);
-//			if (next.startsWith(DefaultFrameWriter.TYPE_AND_ID_STR + " ")) {
-//				currentItem = newItem(next);
-//				_linePoints.put(currentItem.getID(), currentItem);
-//				newFrame.addItem(currentItem);
-//				currentItem.setEncryptionDetailForTag(tag + "", EncryptionDetail.UnencryptedOnSave);
-//			} else if (next.startsWith("SurrogateFor")) {
-//				int parentID = Integer.parseInt(next.split(" ")[1]);
-//				newFrame.getItemWithID(parentID).addToSurrogates(currentItem);
-//				newFrame.addToSurrogates(currentItem);
-//			} else if (currentItem != null && actionShouldBeDelayed(tag.charAt(0))) { 
-//				delayedActions.add(new DelayedAction(currentItem, next));
-//			} else if (currentItem != null) {
-//				processBodyLine(currentItem, next);
-//			} else {
-//				System.err.println("Error while reading in frame (ExpReader): Found body line but no current item to apply it to.");
-//			}
-//		}
-//				
-//		if (next.equals(EncryptedExpWriter.TERMINATOR_WITH_CONTINUATION)) {
-//			next = readTheItems(newFrame, delayedActions);
-//		}
-//		
-//		return next;
-//	}
-	
 	protected String readTheItems(Frame newFrame, List<DelayedAction> delayedActions) throws IOException {
-		// Read the primary item.
-		BiConsumer<Item, String> addToBody = (item, line) -> newFrame.addItem(item);
-		String next = readLineAfterLine(false, addToBody, delayedActions);
-		
-		// Read the surrogate items.
-		if (next.equals(EncryptedExpWriter.TERMINATOR_WITH_CONTINUATION)) {
-			BiConsumer<Item, String> addToSurrogates = (item, line) -> {
-				int parentID = Integer.parseInt(line.split(" ")[1]);
-				newFrame.getItemWithID(parentID).addToSurrogates(item);
-				newFrame.addToSurrogates(item);
-			};
-			next = readLineAfterLine(true, addToSurrogates, delayedActions);
+		BiConsumer<Item, String> primaryAdd = (item, line) -> newFrame.addItem(item);
+		BiConsumer<Item, String> surrogateAdd = (item, line) -> {
+			int parentID = Integer.parseInt(line.split(" ")[1]);
+			Item parent = newFrame.getItemWithID(parentID);
+			newFrame.addToSurrogatesOnLoad(item, parent);
+		};
+		
+		if (_readingSurrogates) {
+			return readLineAfterLine(true, surrogateAdd, delayedActions);
+		} else {
+			return readLineAfterLine(false, primaryAdd, delayedActions);
+		}
+	}
+	
+	@Override
+	protected String readTheConstraints() throws IOException, Exception {
+		String next = null;
+		while (_reader.ready() && !endOfSection.test(next = _reader.readLine())) {
+			if (isValidLine(next)) {
+				Point idtype = separateValues(next.substring(2));
+				// The next line must be the endpoints
+				if (!_reader.ready()) {
+					throw new Exception("Unexpected end of file");
+				}
+				next = _reader.readLine();
+				Point startend = separateValues(next.substring(2));
+
+				Item a = _linePoints.get(startend.getX());
+				Item b = _linePoints.get(startend.getY());
+
+				new Constraint(a, b, idtype.getX(), idtype.getY());
+			}
 		}
 		return next;
@@ -182,5 +178,4 @@
 		Item currentItem = null;
 		
-		Predicate<String> endOfSection = s -> s.equals(EncryptedExpWriter.TERMINATOR + "") || s.equals(EncryptedExpWriter.TERMINATOR_WITH_CONTINUATION);
 		while (_reader.ready() && !endOfSection.test(next = _reader.readLine())) {
 			if (!isValidLine(next)) {
@@ -195,5 +190,6 @@
 					storeResult.accept(currentItem, next);
 				}
-				currentItem.setEncryptionDetailForTag(tag + "", EncryptionDetail.UnencryptedOnSave);
+				EncryptionDetail unencryptedOnSave = new EncryptionDetail(EncryptionDetail.Type.UnencryptedOnSave);
+				currentItem.setEncryptionDetailForTag(tag + "", unencryptedOnSave);
 			} else if (next.startsWith("SurrogateFor")) {
 				if (isSurrogate) {
@@ -212,32 +208,4 @@
 	}
  	
-//	private String readLineAfterLine(Consumer<Item> storeResult, List<DelayedAction> delayedActions) throws IOException {
-//		String next = null;
-//		Item currentItem = null;
-//		
-//		Predicate<String> endOfSection = s -> {
-//			return s.equals(EncryptedExpWriter.TERMINATOR + "") || s.equals(EncryptedExpWriter.TERMINATOR_WITH_CONTINUATION);
-//		};
-//		while (_reader.ready() && !endOfSection.test(next = _reader.readLine())) {
-//			if (!isValidLine(next)) {
-//				continue;
-//			}
-//			
-//			String tag = getTagEnc(next);
-//			if (next.startsWith(DefaultFrameWriter.TYPE_AND_ID_STR + " ")) {
-//				currentItem = newItem(next);
-//				_linePoints.put(currentItem.getID(), currentItem);
-//				currentItem.setEncryptionDetailForTag(tag + "", EncryptionDetail.UnencryptedOnSave);
-//				storeResult.accept(currentItem);
-//			} else if (next.startsWith("SurrogateFor")) {
-//				int parentID = Integer.parseInt(next.split(" ")[1]);
-//				newFrame.getItemWithID(parentID).addToSurrogates(currentItem);
-//				new Delayed
-//			}
-//		}
-//		
-//		return next;
-//	}
-	
 	@Override
 	protected void processBodyLine(Item item, String line) {
@@ -245,24 +213,32 @@
 		String tag = getTagEnc(line);
 		String value = getValue(line);
-		
-		if (item.isSurrogate() && item.isTagInherited(tag)) {
+		boolean isEncryptedLine = isEncryptedLine(line);
+		
+		if (item.isSurrogate() && isEncryptedLine) {
+			// Surrogates should never have encrypted body lines.
 			return;
 		}
 		
 		// Attempt to decrypt the line if necessary.
-		if (isEncryptedLine(line)) {
-			LabelResult res = Label.resolveKey(item.getEncryptionLabel());
+		if (isEncryptedLine) {
+			LabelResult res = Label.getLabel(item.getEncryptionLabel());
 			if (res == LabelResult.SuccessResolveLabelToKey) {
-				item.setEncryptionDetailForTag(tag, EncryptionDetail.ReencryptOnSave);
+				EncryptionDetail reencryptOnSave = new EncryptionDetail(EncryptionDetail.Type.ReencryptOnSave);
+				item.setEncryptionDetailForTag(tag, reencryptOnSave);
 				SecretKey key = new SecretKeySpec(res.key, SymmetricAlgorithm);
 				byte[] decryptedBytes = DecryptSymmetric(Base64.getDecoder().decode(value), key);
 				value = new String(decryptedBytes);				
 			} else {
-				EncryptionDetail encryptionDetail = EncryptionDetail.UseUndecipheredValueOnSave.setUndecipheredValue(getValue(line));
-				item.setEncryptionDetailForTag(tag, encryptionDetail);
+				EncryptionDetail undecipheredValueOnSave = new EncryptionDetail(EncryptionDetail.Type.UseUndecipheredValueOnSave);
+				undecipheredValueOnSave.setUndecipheredValue(getValue(line));
+				item.setEncryptionDetailForTag(tag, undecipheredValueOnSave);
 				return;
 			}
 		} else {
-			item.setEncryptionDetailForTag(tag, EncryptionDetail.UnencryptedOnSave);
+			EncryptionDetail unencryptedOnSave = new EncryptionDetail(EncryptionDetail.Type.UnencryptedOnSave);
+			item.setEncryptionDetailForTag(tag, unencryptedOnSave);
+			if (item.isSurrogate()) {
+				item.setTagNotInherited(tag);
+			}
 		}
 		
@@ -394,5 +370,5 @@
 		
 		private SecretKeySpec resolveLabel(String label) {
-			LabelResult res = Label.resolveKey(label);
+			LabelResult res = Label.getLabel(label);
 			if (res == LabelResult.SuccessResolveLabelToKey) {
 				byte[] keyBytes = res.key;
