diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj
index cb7b23672..3d8a5e71c 100644
--- a/Signal.xcodeproj/project.pbxproj
+++ b/Signal.xcodeproj/project.pbxproj
@@ -348,6 +348,8 @@
 		B66DBF4A19D5BBC8006EA940 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B66DBF4919D5BBC8006EA940 /* Images.xcassets */; };
 		B67ADDC41989FF8700E1A773 /* RPServerRequestsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B67ADDC31989FF8700E1A773 /* RPServerRequestsManager.m */; };
 		B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B67EBF5C19194AC60084CCFD /* Settings.bundle */; };
+		B68112EA1A4D9EC400BA82FF /* UIImage+normalizeImage.m in Sources */ = {isa = PBXBuildFile; fileRef = B68112E91A4D9EC400BA82FF /* UIImage+normalizeImage.m */; };
+		B68112ED1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m in Sources */ = {isa = PBXBuildFile; fileRef = B68112EC1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m */; };
 		B684A46D19C3446200B11029 /* PushManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B684A46C19C3446200B11029 /* PushManagerTest.m */; };
 		B6850E5A1995A4710068E715 /* whisperFake.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6850E591995A4710068E715 /* whisperFake.cer */; };
 		B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; };
@@ -972,6 +974,10 @@
 		B67ADDC21989FF8700E1A773 /* RPServerRequestsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RPServerRequestsManager.h; sourceTree = "<group>"; };
 		B67ADDC31989FF8700E1A773 /* RPServerRequestsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RPServerRequestsManager.m; sourceTree = "<group>"; };
 		B67EBF5C19194AC60084CCFD /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Settings.bundle; path = SettingsBundle/Settings.bundle; sourceTree = SOURCE_ROOT; };
+		B68112E81A4D9EC400BA82FF /* UIImage+normalizeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+normalizeImage.h"; path = "util/UIImage+normalizeImage.h"; sourceTree = "<group>"; };
+		B68112E91A4D9EC400BA82FF /* UIImage+normalizeImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+normalizeImage.m"; path = "util/UIImage+normalizeImage.m"; sourceTree = "<group>"; };
+		B68112EB1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "JSQMessagesCollectionViewCell+menuBarItems.h"; path = "views/JSQMessagesCollectionViewCell+menuBarItems.h"; sourceTree = "<group>"; };
+		B68112EC1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "JSQMessagesCollectionViewCell+menuBarItems.m"; path = "views/JSQMessagesCollectionViewCell+menuBarItems.m"; sourceTree = "<group>"; };
 		B684A46C19C3446200B11029 /* PushManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PushManagerTest.m; path = Signal/test/push/PushManagerTest.m; sourceTree = SOURCE_ROOT; };
 		B6850E591995A4710068E715 /* whisperFake.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperFake.cer; sourceTree = "<group>"; };
 		B69CD25019773E79005CE69A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
@@ -2711,6 +2717,10 @@
 				FCFA64B31A24F3880007FB87 /* UIColor+OWS.m */,
 				FCFA64B51A24F6730007FB87 /* UIFont+OWS.h */,
 				FCFA64B61A24F6730007FB87 /* UIFont+OWS.m */,
+				B68112E81A4D9EC400BA82FF /* UIImage+normalizeImage.h */,
+				B68112E91A4D9EC400BA82FF /* UIImage+normalizeImage.m */,
+				B68112EB1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.h */,
+				B68112EC1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m */,
 			);
 			name = "UI Categories";
 			path = ..;
@@ -3209,6 +3219,7 @@
 				76EB05EA18170B33006006FC /* CallProgress.m in Sources */,
 				FCFA64B41A24F3880007FB87 /* UIColor+OWS.m in Sources */,
 				76EB05C218170B33006006FC /* DhPacketSharedSecretHashes.m in Sources */,
+				B68112ED1A4DA30300BA82FF /* JSQMessagesCollectionViewCell+menuBarItems.m in Sources */,
 				B6B096701A1D25ED008BFAA6 /* TSInfoMessage.m in Sources */,
 				B6C93C4E199567AD00EDF894 /* DebugLogger.m in Sources */,
 				76EB063218170B33006006FC /* Crc32.m in Sources */,
@@ -3275,6 +3286,7 @@
 				B6B0968C1A1D25ED008BFAA6 /* TSDatabaseView.m in Sources */,
 				B6B0966A1A1D25ED008BFAA6 /* IncomingPushMessageSignal.pb.m in Sources */,
 				BFB074C919A5611000F2947C /* ObservableValue.m in Sources */,
+				B68112EA1A4D9EC400BA82FF /* UIImage+normalizeImage.m in Sources */,
 				B6B0968E1A1D25ED008BFAA6 /* TSStorageManager.m in Sources */,
 				FCB11D8A1A1284BB002F93FB /* SettingsTableViewCell.m in Sources */,
 				76EB05C818170B33006006FC /* HelloPacket.m in Sources */,
diff --git a/Signal/src/environment/PreferencesUtil.h b/Signal/src/environment/PreferencesUtil.h
index 0a810a482..d3dfb67f4 100644
--- a/Signal/src/environment/PreferencesUtil.h
+++ b/Signal/src/environment/PreferencesUtil.h
@@ -10,9 +10,10 @@ typedef NS_ENUM(NSUInteger, NotificationType) {
 };
 
 typedef NS_ENUM(NSUInteger, TSImageQuality) {
-    TSImageQualityHigh,
-    TSImageQualityMedium,
-    TSImageQualityLow
+    TSImageQualityUncropped = 1,
+    TSImageQualityHigh      = 2,
+    TSImageQualityMedium    = 3,
+    TSImageQualityLow       = 4
 };
 
 @class PhoneNumber;
diff --git a/Signal/src/environment/PreferencesUtil.m b/Signal/src/environment/PreferencesUtil.m
index 3ccd0d3b9..49a1ef7be 100644
--- a/Signal/src/environment/PreferencesUtil.m
+++ b/Signal/src/environment/PreferencesUtil.m
@@ -135,7 +135,7 @@
     if (preference) {
         return [preference unsignedIntegerValue];
     } else {
-        return TSImageQualityMedium;
+        return TSImageQualityUncropped;
     }
 }
 
diff --git a/Signal/src/textsecure/Contacts/TSThread.h b/Signal/src/textsecure/Contacts/TSThread.h
index 4c5ca03ac..156f7cce8 100644
--- a/Signal/src/textsecure/Contacts/TSThread.h
+++ b/Signal/src/textsecure/Contacts/TSThread.h
@@ -7,8 +7,6 @@
 //
 
 #import <Foundation/Foundation.h>
-#import <YapDatabase/YapDatabaseRelationshipNode.h>
-
 #import "TSYapDatabaseObject.h"
 
 typedef NS_ENUM(NSInteger, TSLastActionType) {
diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h
index 2ef09e91e..d315669ca 100644
--- a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h
+++ b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h
@@ -8,7 +8,7 @@
 
 #import "TSAttachment.h"
 
-@interface TSAttachmentStream : TSAttachment
+@interface TSAttachmentStream : TSAttachment <YapDatabaseRelationshipNode>
 
 - (instancetype)initWithIdentifier:(NSString*)identifier
                               data:(NSData*)data
diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m
index 0b9e548f6..53916f867 100644
--- a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m
+++ b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m
@@ -7,10 +7,13 @@
 //
 
 #import "TSAttachmentStream.h"
+#import "UIImage+contentTypes.h"
+
+NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge";
 
 @interface TSAttachmentStream ()
 
-@property (nonatomic) NSString *path;
+@property (nonatomic) NSString *attachmentPath;
 
 @end
 
@@ -21,9 +24,8 @@
                                key:(NSData*)key
                        contentType:(NSString*)contentType{
     self = [super initWithIdentifier:identifier encryptionKey:key contentType:contentType];
-    
-    NSString *path = [self filePath];
-    [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil];
+
+    [[NSFileManager defaultManager] createFileAtPath:_attachmentPath contents:data attributes:nil];
     
     return self;
 }
@@ -32,10 +34,18 @@
     return YES;
 }
 
+- (NSArray *)yapDatabaseRelationshipEdges {
+    YapDatabaseRelationshipEdge *attachmentFileEdge = [YapDatabaseRelationshipEdge edgeWithName:TSAttachementFileRelationshipEdge
+                                                                            destinationFilePath:[self filePath]
+                                                                                nodeDeleteRules:YDB_DeleteDestinationIfSourceDeleted];
+    
+    return @[attachmentFileEdge];
+}
+
 + (NSString*)attachmentsFolder {
-    NSFileManager* fileManager  = [NSFileManager defaultManager];
-    NSURL *fileURL              = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
-    NSString *path              = [fileURL path];
+    NSFileManager* fileManager = [NSFileManager defaultManager];
+    NSURL *fileURL             = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
+    NSString *path             = [fileURL path];
     NSString *attachmentFolder = [path stringByAppendingFormat:@"/Attachments"];
     
     NSError * error = nil;
@@ -46,7 +56,7 @@
     if (error != nil) {
         DDLogError(@"Failed to create attachments directory: %@", error.description);
     }
-
+    
     return attachmentFolder;
 }
 
@@ -75,7 +85,7 @@
         return nil;
     }
     
-    return [UIImage imageWithContentsOfFile:[self filePath]];
+    return [UIImage imageWithContentsOfFile:self.filePath];
 }
 
 @end
diff --git a/Signal/src/textsecure/Messages/TSMessage.h b/Signal/src/textsecure/Messages/TSMessage.h
index dd6c416c2..100be43e1 100644
--- a/Signal/src/textsecure/Messages/TSMessage.h
+++ b/Signal/src/textsecure/Messages/TSMessage.h
@@ -33,6 +33,6 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage){
 
 - (void)addattachments:(NSArray*)attachments;
 - (void)addattachment:(NSString*)attachment;
-- (BOOL)hasattachments;
+- (BOOL)hasAttachments;
 
 @end
diff --git a/Signal/src/textsecure/Messages/TSMessage.m b/Signal/src/textsecure/Messages/TSMessage.m
index c6d8bb5a6..ac86d42fc 100644
--- a/Signal/src/textsecure/Messages/TSMessage.m
+++ b/Signal/src/textsecure/Messages/TSMessage.m
@@ -7,7 +7,9 @@
 //
 
 #import "TSMessage.h"
+#import "TSAttachment.h"
 
+NSString * const TSAttachementsRelationshipEdgeName = @"TSAttachmentEdge";
 
 @implementation TSMessage
 
@@ -25,10 +27,25 @@
     [self.attachments addObject:attachment];
 }
 
+- (NSArray *)yapDatabaseRelationshipEdges {
+    NSMutableArray *edges = [[super yapDatabaseRelationshipEdges] mutableCopy];
+    
+    if ([self hasAttachments]) {
+        for (NSString *attachmentId in self.attachments) {
+            YapDatabaseRelationshipEdge *fileEdge = [[YapDatabaseRelationshipEdge alloc] initWithName:TSAttachementsRelationshipEdgeName
+                                                                                       destinationKey:attachmentId
+                                                                                           collection:[TSAttachment collection]
+                                                                                      nodeDeleteRules:YDB_DeleteDestinationIfAllSourcesDeleted];
+            [edges addObject:fileEdge];
+        }
+    }
+    return edges;
+}
+
 - (instancetype)initWithTimestamp:(uint64_t)timestamp
                          inThread:(TSThread*)thread
                       messageBody:(NSString*)body
-                     attachments:(NSArray*)attachments
+                      attachments:(NSArray*)attachments
 {
     self = [super initWithTimestamp:timestamp inThread:thread];
     
@@ -39,13 +56,13 @@
     return self;
 }
 
-- (BOOL)hasattachments{
+- (BOOL)hasAttachments{
     return self.attachments?(self.attachments.count>0):false;
 }
 
 - (NSString *)description{
     if(self.attachments > 0){
-        return @"attachment";
+        return @"Attachment";
     } else {
         return self.body;
     }
diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m b/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m
index 45d129fdd..11c9acca1 100644
--- a/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m
+++ b/Signal/src/textsecure/Messages/TSMessagesManager+attachments.m
@@ -46,6 +46,7 @@ dispatch_queue_t attachmentsQueue() {
         for (PushMessageContentAttachmentPointer *pointer in content.attachments) {
             TSAttachmentPointer *attachmentPointer = [[TSAttachmentPointer alloc] initWithIdentifier:pointer.id key:pointer.key contentType:pointer.contentType relay:message.relay];
             [attachmentPointer saveWithTransaction:transaction];
+            
             dispatch_async(attachmentsQueue(), ^{
                 [self retrieveAttachment:attachmentPointer];
             });
@@ -57,7 +58,7 @@ dispatch_queue_t attachmentsQueue() {
 }
 
 - (void)sendAttachment:(NSData*)attachmentData contentType:(NSString*)contentType thread:(TSThread*)thread {
-    
+
     TSRequest *allocateAttachment = [[TSAllocAttachmentRequest alloc] init];
     [[TSNetworkManager sharedManager] queueAuthenticatedRequest:allocateAttachment success:^(NSURLSessionDataTask *task, id responseObject) {
         dispatch_async(attachmentsQueue(), ^{
@@ -174,4 +175,5 @@ dispatch_queue_t attachmentsQueue() {
     return success;
 }
 
+
 @end
diff --git a/Signal/src/util/UIImage+normalizeImage.h b/Signal/src/util/UIImage+normalizeImage.h
new file mode 100644
index 000000000..6f5746ebe
--- /dev/null
+++ b/Signal/src/util/UIImage+normalizeImage.h
@@ -0,0 +1,15 @@
+//
+//  UIImage+normalizeImage.h
+//  Signal
+//
+//  Created by Frederic Jacobs on 26/12/14.
+//  Copyright (c) 2014 Open Whisper Systems. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface UIImage (normalizeImage)
+
+- (UIImage *)normalizedImage;
+
+@end
diff --git a/Signal/src/util/UIImage+normalizeImage.m b/Signal/src/util/UIImage+normalizeImage.m
new file mode 100644
index 000000000..855f80df2
--- /dev/null
+++ b/Signal/src/util/UIImage+normalizeImage.m
@@ -0,0 +1,23 @@
+//
+//  UIImage+normalizeImage.m
+//  Signal
+//
+//  Created by Frederic Jacobs on 26/12/14.
+//  Copyright (c) 2014 Open Whisper Systems. All rights reserved.
+//
+
+#import "UIImage+normalizeImage.h"
+
+@implementation UIImage (normalizeImage)
+
+- (UIImage *)normalizedImage {
+    if (self.imageOrientation == UIImageOrientationUp) return self;
+    
+    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
+    [self drawInRect:(CGRect){0, 0, self.size}];
+    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    return normalizedImage;
+}
+
+@end
diff --git a/Signal/src/util/UIUtil.h b/Signal/src/util/UIUtil.h
index d9e2d2106..97d608655 100644
--- a/Signal/src/util/UIUtil.h
+++ b/Signal/src/util/UIUtil.h
@@ -2,6 +2,8 @@
 
 #import "UIColor+OWS.h"
 #import "UIFont+OWS.h"
+#import "UIImage+normalizeImage.h"
+#import "UIImage+contentTypes.h"
 
 /**
  *
diff --git a/Signal/src/util/UIUtil.m b/Signal/src/util/UIUtil.m
index aadff305c..57e3c06ee 100644
--- a/Signal/src/util/UIUtil.m
+++ b/Signal/src/util/UIUtil.m
@@ -4,7 +4,6 @@
 
 @implementation UIUtil
 
-
 + (void)applyRoundedBorderToImageView:(UIImageView *__strong*)imageView {
     [[*imageView layer] setBorderWidth:CONTACT_PICTURE_VIEW_BORDER_WIDTH];
     [[*imageView layer] setBorderColor:[[UIColor lightGrayColor] CGColor]];
diff --git a/Signal/src/view controllers/FullImageViewController.h b/Signal/src/view controllers/FullImageViewController.h
index d3837070d..a63347cc5 100644
--- a/Signal/src/view controllers/FullImageViewController.h	
+++ b/Signal/src/view controllers/FullImageViewController.h	
@@ -7,11 +7,13 @@
 //
 
 #import <UIKit/UIKit.h>
+#import "TSAttachmentStream.h"
+#import "TSInteraction.h"
 
 @interface FullImageViewController : UIViewController
 
-- (instancetype)initWithImage:(UIImage*)image fromRect:(CGRect)rect;
+- (instancetype)initWithAttachment:(TSAttachmentStream*)attachment fromRect:(CGRect)rect forInteraction:(TSInteraction*)interaction;
 
--(void)presentFromViewController:(UIViewController*)viewController;
+- (void)presentFromViewController:(UIViewController*)viewController;
 
 @end
diff --git a/Signal/src/view controllers/FullImageViewController.m b/Signal/src/view controllers/FullImageViewController.m
index f2b6765d6..b6d82463e 100644
--- a/Signal/src/view controllers/FullImageViewController.m	
+++ b/Signal/src/view controllers/FullImageViewController.m	
@@ -8,6 +8,7 @@
 
 #import "FullImageViewController.h"
 #import "DJWActionSheet.h"
+#import "TSAttachmentStream.h"
 
 #define kImageViewCornerRadius 5.0f
 
@@ -24,7 +25,6 @@
 @property (nonatomic, strong) UIScrollView *scrollView;
 
 @property (nonatomic, strong) UIImageView *imageView;
-@property (nonatomic, strong) UIImage* image;
 
 @property (nonatomic, strong) UITapGestureRecognizer *singleTap;
 @property (nonatomic, strong) UITapGestureRecognizer *doubleTap;
@@ -34,23 +34,31 @@
 @property CGRect originRect;
 @property BOOL isPresenting;
 
+@property TSAttachmentStream *attachment;
+@property TSInteraction      *interaction;
+
 @end
 
 @implementation FullImageViewController
 
 
-- (instancetype)initWithImage:(UIImage*)image fromRect:(CGRect)rect {
+- (instancetype)initWithAttachment:(TSAttachmentStream*)attachment fromRect:(CGRect)rect forInteraction:(TSInteraction*)interaction {
     self = [super initWithNibName:nil bundle:nil];
     
     if  (self) {
-        self.image = image;
-        self.imageView.image = image;
-        self.originRect = rect;
+        self.attachment      = attachment;
+        self.imageView.image = self.image;
+        self.originRect      = rect;
+        self.interaction     = interaction;
     }
     
     return self;
 }
 
+- (UIImage*)image{
+    return self.attachment.image;
+}
+
 - (void)viewDidLoad {
     [super viewDidLoad];
     
@@ -353,11 +361,14 @@
 {
     [DJWActionSheet showInView:self.view withTitle:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:@[@"Save to Camera Roll", @"Copy"] tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
         if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
+
+        } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex){
+            __block TSInteraction *interaction = [self interaction];
+            [self dismissViewControllerAnimated:YES completion:^{
+                [interaction remove];
+            }];
             
-        } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
-            #warning Unimplemented deleting attachments from FullImageView
-            NSLog(@"Destructive button tapped");
-        }else {
+        } else {
             switch (tappedButtonIndex) {
                 case 0:
                     UIImageWriteToSavedPhotosAlbum(self.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
diff --git a/Signal/src/view controllers/MessagesViewController.h b/Signal/src/view controllers/MessagesViewController.h
index bb42cb900..adbfa6431 100644
--- a/Signal/src/view controllers/MessagesViewController.h	
+++ b/Signal/src/view controllers/MessagesViewController.h	
@@ -11,11 +11,12 @@
 #import "GroupModel.h"
 @class TSThread;
 
-@interface MessagesViewController : JSQMessagesViewController <UIImagePickerControllerDelegate,UINavigationControllerDelegate>
+@interface MessagesViewController : JSQMessagesViewController   <UIImagePickerControllerDelegate,
+                                                                UINavigationControllerDelegate,
+                                                                UITextViewDelegate>
 
 - (void)setupWithThread:(TSThread*)thread;
 - (void)setupWithTSIdentifier:(NSString*)identifier;
 - (void)setupWithTSGroup:(GroupModel*)model;
 
-
 @end
diff --git a/Signal/src/view controllers/MessagesViewController.m b/Signal/src/view controllers/MessagesViewController.m
index 5dcda79d5..536507f52 100644
--- a/Signal/src/view controllers/MessagesViewController.m	
+++ b/Signal/src/view controllers/MessagesViewController.m	
@@ -133,7 +133,6 @@ typedef enum : NSUInteger {
 -(void)viewWillAppear:(BOOL)animated
 {
     [super viewWillAppear:animated];
-    self.automaticallyScrollsToMostRecentMessage = YES;
     [self scrollToBottomAnimated:NO];
 }
 
@@ -164,7 +163,7 @@ typedef enum : NSUInteger {
 -(void)initializeNavigationBar
 {
     self.title = self.thread.name;
-
+    
     if (!isGroupConversation && [self isRedPhoneReachable]) {
         UIBarButtonItem * lockButton = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"lock"] style:UIBarButtonItemStylePlain target:self action:@selector(showFingerprint)];
         UIBarButtonItem * callButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"call_tab"] style:UIBarButtonItemStylePlain target:self action:@selector(callAction)];
@@ -197,7 +196,7 @@ typedef enum : NSUInteger {
         self.collectionView.showsVerticalScrollIndicator = NO;
         self.collectionView.showsHorizontalScrollIndicator = NO;
         
-        self.automaticallyScrollsToMostRecentMessage = NO;
+        self.automaticallyScrollsToMostRecentMessage = YES;
         
         self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
         self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
@@ -298,24 +297,18 @@ typedef enum : NSUInteger {
     switch (msg.messageType) {
         case TSIncomingMessageAdapter:
             return [self loadIncomingMessageCellForMessage:msg atIndexPath:indexPath];
-            break;
         case TSOutgoingMessageAdapter:
             return [self loadOutgoingCellForMessage:msg atIndexPath:indexPath];
-            break;
         case TSCallAdapter:
             return [self loadCallCellForCall:msg atIndexPath:indexPath];
-            break;
         case TSInfoMessageAdapter:
             return [self loadInfoMessageCellForMessage:msg atIndexPath:indexPath];
-            break;
         case TSErrorMessageAdapter:
             return [self loadErrorMessageCellForMessage:msg atIndexPath:indexPath];
-            break;
             
         default:
             NSLog(@"Something went wrong");
             return nil;
-            break;
     }
 }
 
@@ -325,7 +318,8 @@ typedef enum : NSUInteger {
 {
     JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:self.collectionView cellForItemAtIndexPath:indexPath];
     if (!message.isMediaMessage) {
-        cell.textView.textColor = [UIColor blackColor];
+        cell.textView.textColor          = [UIColor blackColor];
+        cell.textView.selectable         = NO;
         cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor,
                                               NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) };
     }
@@ -338,7 +332,8 @@ typedef enum : NSUInteger {
     JSQMessagesCollectionViewCell *cell = (JSQMessagesCollectionViewCell *)[super collectionView:self.collectionView cellForItemAtIndexPath:indexPath];
     if (!message.isMediaMessage)
     {
-        cell.textView.textColor = [UIColor whiteColor];
+        cell.textView.textColor          = [UIColor whiteColor];
+        cell.textView.selectable         = NO;
         cell.textView.linkTextAttributes = @{ NSForegroundColorAttributeName : cell.textView.textColor,
                                               NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle | NSUnderlinePatternSolid) };
     }
@@ -497,6 +492,7 @@ typedef enum : NSUInteger {
     TSMessageAdapter *messageItem = [collectionView.dataSource collectionView:collectionView messageDataForItemAtIndexPath:indexPath];
     TSInteraction    *interaction = [self interactionAtIndexPath:indexPath];
     
+    
     switch (messageItem.messageType) {
         case TSOutgoingMessageAdapter:
             if (messageItem.messageState == TSOutgoingMessageStateUnsent) {
@@ -507,15 +503,21 @@ typedef enum : NSUInteger {
             BOOL isMediaMessage = [messageItem isMediaMessage];
             
             if (isMediaMessage) {
-                TSAttachmentAdapter * messageMedia = (TSAttachmentAdapter*)[messageItem media];
+                TSAttachmentAdapter* messageMedia = (TSAttachmentAdapter*)[messageItem media];
                 
                 if ([messageMedia isImage]) {
-                    //is a photo
-                    tappedImage = ((UIImageView*)[messageMedia mediaView]).image ;
+                    tappedImage = ((UIImageView*)[messageMedia mediaView]).image;
                     CGRect convertedRect = [self.collectionView convertRect:[collectionView cellForItemAtIndexPath:indexPath].frame toView:nil];
-                    FullImageViewController * vc = [[FullImageViewController alloc]initWithImage:tappedImage fromRect:convertedRect];
-                    [vc presentFromViewController:self];
+                    __block TSAttachment *attachment = nil;
+                    [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
+                        attachment = [TSAttachment fetchObjectWithUniqueID:messageMedia.attachmentId transaction:transaction];
+                    }];
                     
+                    if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
+                        TSAttachmentStream *attStream = (TSAttachmentStream*)attachment;
+                        FullImageViewController * vc = [[FullImageViewController alloc] initWithAttachment:attStream fromRect:convertedRect forInteraction:[self interactionAtIndexPath:indexPath]];
+                        [vc presentFromViewController:self];
+                    }
                 } else {
                     DDLogWarn(@"Currently unsupported");
                 }
@@ -550,6 +552,13 @@ typedef enum : NSUInteger {
     }];
 }
 
+- (void)deleteMessageAtIndexPath:(NSIndexPath*)indexPath {
+    [self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
+        TSInteraction *interaction = [self interactionAtIndexPath:indexPath];
+        [interaction removeWithTransaction:transaction];
+    }];
+}
+
 - (void)handleErrorMessageTap:(TSErrorMessage*)message{
     if (message.errorType == TSErrorMessageWrongTrustedIdentityKey) {
         NSString *newKeyFingerprint = [message newIdentityKey];
@@ -615,9 +624,8 @@ typedef enum : NSUInteger {
     picker.sourceType = UIImagePickerControllerSourceTypeCamera;
     
     if ([UIImagePickerController isSourceTypeAvailable:
-         UIImagePickerControllerSourceTypeCamera])
-    {
-        picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *)kUTTypeMovie, kUTTypeImage, kUTTypeVideo, nil];
+         UIImagePickerControllerSourceTypeCamera]) {
+        picker.mediaTypes = @[(NSString*)kUTTypeImage];
         [self presentViewController:picker animated:YES completion:NULL];
     }
     
@@ -655,7 +663,7 @@ typedef enum : NSUInteger {
 
 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
 {
-    UIImage *picture_camera = [info objectForKey:UIImagePickerControllerOriginalImage];
+    UIImage *picture_camera = [[info objectForKey:UIImagePickerControllerOriginalImage] normalizedImage];
     
     NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
     
@@ -680,6 +688,9 @@ typedef enum : NSUInteger {
 {
     CGFloat correctedWidth;
     switch ([Environment.preferences imageUploadQuality]) {
+        case TSImageQualityUncropped:
+            return image;
+            
         case TSImageQualityHigh:
             correctedWidth = 2048;
             break;
@@ -721,15 +732,14 @@ typedef enum : NSUInteger {
 -(CGFloat)compressionRate
 {
     switch ([Environment.preferences imageUploadQuality]) {
+        case TSImageQualityUncropped:
+            return 1;
         case TSImageQualityHigh:
             return 0.9f;
-            break;
         case TSImageQualityMedium:
             return 0.5f;
-            break;
         case TSImageQualityLow:
             return 0.3f;
-            break;
         default:
             break;
     }
@@ -853,7 +863,7 @@ typedef enum : NSUInteger {
                      withTitle:nil
              cancelButtonTitle:@"Cancel"
         destructiveButtonTitle:nil
-             otherButtonTitles:@[@"Update group", @"Leave group", @"Delete thread"]
+             otherButtonTitles:@[@"Update group", @"Leave group"]
                       tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
                           if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
                               NSLog(@"User Cancelled");
@@ -867,12 +877,9 @@ typedef enum : NSUInteger {
                                       
                                       break;
                                   case 1:
-                                      DDLogDebug(@"leave group picket");
+                                      DDLogDebug(@"leave group picked");
                                       break;
-                                  case 2:
-                                      DDLogDebug(@"delete thread");
-                                      break;
-                                      
+
                                   default:
                                       break;
                               }
@@ -893,12 +900,12 @@ typedef enum : NSUInteger {
                      withTitle:nil
              cancelButtonTitle:@"Cancel"
         destructiveButtonTitle:nil
-             otherButtonTitles:@[@"Take Photo or Video", @"Choose existing Photo", @"Choose existing Video", @"Send file"]
+             otherButtonTitles:@[@"Take Photo", @"Choose existing Photo"]
                       tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
                           if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
-                              NSLog(@"User Cancelled");
+                              DDLogVerbose(@"User Cancelled");
                           } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) {
-                              NSLog(@"Destructive button tapped");
+                              DDLogVerbose(@"Destructive button tapped");
                           }else {
                               switch (tappedButtonIndex) {
                                   case 0:
@@ -907,10 +914,6 @@ typedef enum : NSUInteger {
                                   case 1:
                                       [self chooseFromLibrary:kMediaTypePicture];
                                       break;
-                                  case 2:
-                                      [self chooseFromLibrary:kMediaTypeVideo];
-                                      break;
-                                      
                                   default:
                                       break;
                               }
@@ -932,6 +935,26 @@ typedef enum : NSUInteger {
     }];
 }
 
+
+- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
+{
+    if (action == @selector(delete:)) {
+        return YES;
+    }
+    
+    return [super collectionView:collectionView canPerformAction:action forItemAtIndexPath:indexPath withSender:sender];
+}
+
+- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
+{
+    if (action == @selector(delete:)) {
+        [self deleteMessageAtIndexPath:indexPath];
+    }
+    else {
+        [super collectionView:collectionView performAction:action forItemAtIndexPath:indexPath withSender:sender];
+    }
+}
+
 - (void)dealloc{
     [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
diff --git a/Signal/src/view controllers/SettingsTableViewCell.m b/Signal/src/view controllers/SettingsTableViewCell.m
index 65a7fbc82..3724e4956 100644
--- a/Signal/src/view controllers/SettingsTableViewCell.m	
+++ b/Signal/src/view controllers/SettingsTableViewCell.m	
@@ -43,6 +43,9 @@
 -(void)updateImageQualityLabel
 {
     switch ([Environment.preferences imageUploadQuality]) {
+        case TSImageQualityUncropped:
+            self.detailLabel.text = @"Full";
+            break;
         case TSImageQualityHigh:
             self.detailLabel.text = @"High";
             break;
diff --git a/Signal/src/view controllers/SettingsTableViewController.m b/Signal/src/view controllers/SettingsTableViewController.m
index 471932411..be8b6a1d4 100644
--- a/Signal/src/view controllers/SettingsTableViewController.m	
+++ b/Signal/src/view controllers/SettingsTableViewController.m	
@@ -125,7 +125,7 @@ typedef enum {
                                  withTitle:nil
                          cancelButtonTitle:@"Cancel"
                     destructiveButtonTitle:nil
-                         otherButtonTitles:@[@"High", @"Medium", @"Low"]
+                         otherButtonTitles:@[@"Uncompressed", @"High", @"Medium", @"Low"]
                                   tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) {
                                       [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
                                       if (tappedButtonIndex == actionSheet.cancelButtonIndex) {
@@ -136,12 +136,15 @@ typedef enum {
                                       }else {
                                           switch (tappedButtonIndex) {
                                               case 0:
-                                                  [Environment.preferences setImageUploadQuality:TSImageQualityHigh];
+                                                  [Environment.preferences setImageUploadQuality:TSImageQualityUncropped];
                                                   break;
                                               case 1:
-                                                  [Environment.preferences setImageUploadQuality:TSImageQualityMedium];
+                                                  [Environment.preferences setImageUploadQuality:TSImageQualityHigh];
                                                   break;
                                               case 2:
+                                                  [Environment.preferences setImageUploadQuality:TSImageQualityMedium];
+                                                  break;
+                                              case 3:
                                                   [Environment.preferences setImageUploadQuality:TSImageQualityLow];
                                                   break;
                                               default:
diff --git a/Signal/src/view controllers/TSAttachmentAdapter.h b/Signal/src/view controllers/TSAttachmentAdapter.h
index f3765867a..1e8c0a889 100644
--- a/Signal/src/view controllers/TSAttachmentAdapter.h	
+++ b/Signal/src/view controllers/TSAttachmentAdapter.h	
@@ -16,4 +16,6 @@
 
 - (BOOL)isImage;
 
+@property NSString *attachmentId;
+
 @end
diff --git a/Signal/src/view controllers/TSAttachmentAdapter.m b/Signal/src/view controllers/TSAttachmentAdapter.m
index 917d9e3e1..c5c1babbd 100644
--- a/Signal/src/view controllers/TSAttachmentAdapter.m	
+++ b/Signal/src/view controllers/TSAttachmentAdapter.m	
@@ -16,8 +16,6 @@
 @property UIImage *image;
 
 @property (strong, nonatomic) UIImageView *cachedImageView;
-@property (assign, nonatomic, readonly) BOOL isImageAttachment;
-
 @end
 
 @implementation TSAttachmentAdapter
@@ -26,9 +24,9 @@
     self = [super init];
     
     if (self) {
-        _image = [UIImage imageWithCGImage:attachment.image.CGImage];
+        _image           = attachment.image;
         _cachedImageView = nil;
-        _isImageAttachment = YES;
+        _attachmentId    = attachment.uniqueId;
     }
     return self;
 }
@@ -73,7 +71,7 @@
 
 -(BOOL)isImage
 {
-    return _isImageAttachment;
+    return YES;
 }
 
 #pragma mark - Utility
@@ -100,7 +98,6 @@
     return ratio > 1.0f ? [self smallPortraitSize] : [self smallLandscapeSize];
 }
 
-
 - (CGSize)largePortraitSize
 {
     return CGSizeMake(220.0f, 310.0f);
diff --git a/Signal/src/view controllers/TSMessageAdapter.m b/Signal/src/view controllers/TSMessageAdapter.m
index 8c661dd41..09ea9de6e 100644
--- a/Signal/src/view controllers/TSMessageAdapter.m	
+++ b/Signal/src/view controllers/TSMessageAdapter.m	
@@ -15,6 +15,7 @@
 #import "TSattachment.h"
 #import "TSAttachmentStream.h"
 #import "TSAttachmentAdapter.h"
+#import "TSAttachmentPointer.h"
 
 @interface TSMessageAdapter ()
 
@@ -92,13 +93,23 @@
             
             for (NSString *attachmentID in message.attachments) {
                 TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentID];
-                
+    
                 if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
                     TSAttachmentStream *stream = (TSAttachmentStream*)attachment;
                     if ([stream isImage]) {
                         adapter.mediaItem = [[TSAttachmentAdapter alloc] initWithAttachment:stream];
                         adapter.mediaItem.appliesMediaViewMaskAsOutgoing = [interaction isKindOfClass:[TSOutgoingMessage class]];
+                        break;
+                    } else {
+                        DDLogWarn(@"We have a TSAttachmentStream for an unsupported media type");
                     }
+                } else if ([attachment isKindOfClass:[TSAttachmentPointer class]]){
+                    //TSAttachmentPointer *pointer = (TSAttachmentPointer*)attachment;
+                    //TODO: Change this status when download failed;
+                    adapter.messageBody = @"Attachment is downloading";
+                    adapter.messageType = TSInfoMessageAdapter;
+                } else {
+                    DDLogError(@"We retreived an attachment that doesn't have a known type : %@", NSStringFromClass([attachment class]));
                 }
             }
         }
diff --git a/Signal/src/views/JSQMessagesCollectionViewCell+menuBarItems.h b/Signal/src/views/JSQMessagesCollectionViewCell+menuBarItems.h
new file mode 100644
index 000000000..1baf6cb26
--- /dev/null
+++ b/Signal/src/views/JSQMessagesCollectionViewCell+menuBarItems.h
@@ -0,0 +1,13 @@
+//
+//  JSQMessagesCollectionViewCell+menuBarItems.h
+//  Signal
+//
+//  Created by Frederic Jacobs on 26/12/14.
+//  Copyright (c) 2014 Open Whisper Systems. All rights reserved.
+//
+
+#import "JSQMessagesCollectionViewCell.h"
+
+@interface JSQMessagesCollectionViewCell (menuBarItems)
+
+@end
diff --git a/Signal/src/views/JSQMessagesCollectionViewCell+menuBarItems.m b/Signal/src/views/JSQMessagesCollectionViewCell+menuBarItems.m
new file mode 100644
index 000000000..958d02e27
--- /dev/null
+++ b/Signal/src/views/JSQMessagesCollectionViewCell+menuBarItems.m
@@ -0,0 +1,49 @@
+//
+//  JSQMessagesCollectionViewCell+menuBarItems.m
+//  Signal
+//
+//  Created by Frederic Jacobs on 26/12/14.
+//  Copyright (c) 2014 Open Whisper Systems. All rights reserved.
+//
+
+#import "JSQMessagesCollectionViewCell+menuBarItems.h"
+
+@implementation JSQMessagesCollectionViewCell (menuBarItems)
+
+- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
+{
+    if (action == @selector(delete:)) {
+        return YES;
+    }
+    
+    return [super canPerformAction:action withSender:sender];
+}
+
+- (void)delete:(id)sender
+{
+    [self performSelectorOnParentCollectionView:@selector(delete:)
+                                     withSender:sender];
+}
+
+- (void)performSelectorOnParentCollectionView:(SEL)selector
+                                   withSender:(id)sender {
+    UIView *view = self;
+    do {
+        view = view.superview;
+    } while (![view isKindOfClass:[UICollectionView class]]);
+    UICollectionView *collectionView = (UICollectionView *)view;
+    NSIndexPath *indexPath = [collectionView indexPathForCell:self];
+    
+    if (collectionView.delegate &&
+        [collectionView.delegate respondsToSelector:@selector(collectionView:
+                                                              performAction:
+                                                              forItemAtIndexPath:
+                                                              withSender:)])
+        
+        [collectionView.delegate collectionView:collectionView
+                                  performAction:selector
+                             forItemAtIndexPath:indexPath
+                                     withSender:sender];
+}   
+
+@end