Index: /trunk/src/org/expeditee/core/Image.java
===================================================================
--- /trunk/src/org/expeditee/core/Image.java	(revision 1425)
+++ /trunk/src/org/expeditee/core/Image.java	(revision 1426)
@@ -147,4 +147,8 @@
 	}
 	
+	public static Image getNoise() {
+		return _manager.getNoise();
+	}
+	
 	/** Convenience access to ImageManager.getImage(URL). */
 	public static Image getImage(URL url)
Index: /trunk/src/org/expeditee/gio/ImageManager.java
===================================================================
--- /trunk/src/org/expeditee/gio/ImageManager.java	(revision 1425)
+++ /trunk/src/org/expeditee/gio/ImageManager.java	(revision 1426)
@@ -5,4 +5,5 @@
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.Random;
 
 import org.expeditee.core.Colour;
@@ -75,4 +76,22 @@
 	public abstract Image getImage(String filename);
 	
+	/** Gets an image that is just noise */
+	public Image getNoise() {
+		int width = 100;
+		int height = 100;
+		int[] pixelData = new int[width * height];
+		Random rand = new Random();
+		
+		for (int i = 0; i < pixelData.length; i++) {
+			int alpha = rand.nextInt(256) << 24;
+			int red = rand.nextInt(256) << 16;
+			int green = rand.nextInt(256) << 8;
+			int blue = rand.nextInt(256);
+			pixelData[i] = alpha | red | green | blue;
+		} 
+		
+		return createImage(width, height, pixelData);
+	}
+	
 	/** Gets image data from a HTTP connection. */
 	public abstract Image getImage(HttpURLConnection connection) throws IOException;
@@ -125,5 +144,4 @@
 	
 	/** Writes the image data to disk. Format should be png, bmp, etc. */
-	public abstract boolean writeImageToDisk(Image image, String format, File file) throws IOException;
-	
+	public abstract boolean writeImageToDisk(Image image, String format, File file) throws IOException;	
 }
Index: /trunk/src/org/expeditee/gui/Frame.java
===================================================================
--- /trunk/src/org/expeditee/gui/Frame.java	(revision 1425)
+++ /trunk/src/org/expeditee/gui/Frame.java	(revision 1426)
@@ -26,4 +26,5 @@
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
@@ -2823,4 +2824,12 @@
 			if (i.isVisible()) {
 				_interactableItems.add(i);
+			} else {
+				Collection<? extends XRayable> enclosures = i.getEnclosures();
+				if (enclosures != null && !enclosures.isEmpty()) {
+					Iterator<? extends XRayable> iterator = enclosures.iterator();
+					while (iterator.hasNext()) {
+						_interactableItems.add(iterator.next());
+					}
+				}
 			}
 		}
Index: /trunk/src/org/expeditee/items/Item.java
===================================================================
--- /trunk/src/org/expeditee/items/Item.java	(revision 1425)
+++ /trunk/src/org/expeditee/items/Item.java	(revision 1426)
@@ -4052,5 +4052,22 @@
 		if (copy.isAnnotation()) {
 			if (ItemUtils.startsWithTag(copy, ItemUtils.TAG_IMAGE, true)) {
-				copy.setText(ItemUtils.GetTag(ItemUtils.TAG_IMAGE) + ": redacted.png");
+				String text = copy.getText();
+				String size = "";
+				
+				// remove @i tag
+				text = text.replaceFirst("@i:", "");
+				text = text.replaceAll("\n", "");
+				text = text.trim();
+
+				int dotPos = text.indexOf('.');
+				if (dotPos >= 0) {
+					int endOfFileNamePos = text.indexOf(' ', dotPos);
+					if (endOfFileNamePos >= 0) {
+						size = text.substring(endOfFileNamePos).trim();
+					}
+				}
+				
+				String copyText = ItemUtils.GetTag(ItemUtils.TAG_IMAGE) + ": " + Picture.REDACTED_IMAGE_NAME + " " + size;
+				copy.setText(copyText.trim());
 				copy.setVisible(true);
 			}
Index: /trunk/src/org/expeditee/items/ItemUtils.java
===================================================================
--- /trunk/src/org/expeditee/items/ItemUtils.java	(revision 1425)
+++ /trunk/src/org/expeditee/items/ItemUtils.java	(revision 1426)
@@ -400,48 +400,49 @@
 			}
 			fileName = path;
-
-			// try images subdirectory
-			File file = null;
-
-			for (String dir : FolderSettings.ImageDirs.getAbsoluteDirs()) {
-				file = new File(dir + path);
-				if (file.exists() && !file.isDirectory()) {
-					break;
-				}
-			}
-
-			if (file == null || !file.exists() || file.isDirectory()) {
+			
+			if (!fileName.equals(Picture.REDACTED_IMAGE_NAME)) {
+				// try images subdirectory
+				File file = null;
+
+				for (String dir : FolderSettings.ImageDirs.getAbsoluteDirs()) {
+					file = new File(dir + path);
+					if (file.exists() && !file.isDirectory()) {
+						break;
+					}
+				}
+
+				if (file == null || !file.exists() || file.isDirectory()) {
+					file = new File(path);
+				}
+
+				// try relative path
+				if (!file.exists() || file.isDirectory()) {
+					URL picture = new Object().getClass().getResource(path);
+
+					// decode to remove %20 in windows folder names
+					if (picture != null) {
+						try {
+							path = URLDecoder.decode(picture.getFile(), "UTF-8");
+						} catch (UnsupportedEncodingException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+
+				} else {
+					path = file.getPath();
+				}
+
+				// if the image isn't found by now, try remote servers
 				file = new File(path);
-			}
-
-			// try relative path
-			if (!file.exists() || file.isDirectory()) {
-				URL picture = new Object().getClass().getResource(path);
-
-				// decode to remove %20 in windows folder names
-				if (picture != null) {
-					try {
-						path = URLDecoder.decode(picture.getFile(), "UTF-8");
-					} catch (UnsupportedEncodingException e) {
-						// TODO Auto-generated catch block
-						e.printStackTrace();
-					}
-				}
-
-			} else {
-				path = file.getPath();
-			}
-
-			// if the image isn't found by now, try remote servers
-			file = new File(path);
-			if (!file.exists() || file.isDirectory()) {
-       			if(tryRemote && FrameShare.getInstance().loadImage(fileName, null)) {
-       				// call CreatePicture again, but with tryRemote set to false so we won't get into an infinite loop
-       				// if something goes wrong with finding the downloaded image
-       				return CreatePicture(source, false);
-       			}
-				return null;
-			}
-
+				if (!file.exists() || file.isDirectory()) {
+	       			if(tryRemote && FrameShare.getInstance().loadImage(fileName, null)) {
+	       				// call CreatePicture again, but with tryRemote set to false so we won't get into an infinite loop
+	       				// if something goes wrong with finding the downloaded image
+	       				return CreatePicture(source, false);
+	       			}
+					return null;
+				}
+			}
 		} catch (Exception e) {
 			return null;
Index: /trunk/src/org/expeditee/items/Picture.java
===================================================================
--- /trunk/src/org/expeditee/items/Picture.java	(revision 1425)
+++ /trunk/src/org/expeditee/items/Picture.java	(revision 1426)
@@ -62,4 +62,6 @@
 public class Picture extends XRayable {
 	
+	public static final String REDACTED_IMAGE_NAME = "redacted.png";
+	
 	private static final float CROPPING_COMPOSITE_ALPHA = 0.5f;
 
@@ -146,4 +148,10 @@
 		parseSize();
 	}
+	
+	public boolean isNoise() {
+		return _fileName.equals(REDACTED_IMAGE_NAME);
+	}
+	
+	
 
 	protected String getImageSize() {
@@ -788,5 +796,11 @@
 		}
 */
-		_image = Image.getImage(_path);
+		
+		if (isNoise()) {
+			_image = Image.getNoise();
+		} else {
+			_image = Image.getImage(_path);
+		}
+		
 		return true;
 	}
Index: /trunk/src/org/expeditee/items/XRayable.java
===================================================================
--- /trunk/src/org/expeditee/items/XRayable.java	(revision 1425)
+++ /trunk/src/org/expeditee/items/XRayable.java	(revision 1426)
@@ -41,4 +41,14 @@
 	
 	@Override
+	public Item getPrimary() {
+		return _source.getPrimary();
+	}
+	
+	@Override
+	public boolean isSurrogate() {
+		return _source.isSurrogate();
+	}
+	
+	@Override
 	public void setEncryptionLabel(String label) {
 		_source.setEncryptionLabel(label);
