diff --git a/ObjectivePGP.framework/Info.plist b/ObjectivePGP.framework/Info.plist
index 39de5613232d667e6792fb58a8e8b29be36ba34b..07167478d196b99ed5f2bbe3d308e80c8fee002d 100644
Binary files a/ObjectivePGP.framework/Info.plist and b/ObjectivePGP.framework/Info.plist differ
diff --git a/ObjectivePGP.framework/ObjectivePGP b/ObjectivePGP.framework/ObjectivePGP
index d055662492d5c48d881aa65eee82d996e9d6fc20..a8326c2d5a202d74ae14728798b1b4f77c5df0b2 100755
Binary files a/ObjectivePGP.framework/ObjectivePGP and b/ObjectivePGP.framework/ObjectivePGP differ
diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj
index d3afdb029c92e8e11262f34ffc2a7f11c44cc207..df510eb6269d3dc38d9e3936650c92551c40d77a 100644
--- a/enzevalos_iphone.xcodeproj/project.pbxproj
+++ b/enzevalos_iphone.xcodeproj/project.pbxproj
@@ -14,10 +14,8 @@
 		3EC35F2420037651008BDF95 /* InvitationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EC35F2320037651008BDF95 /* InvitationHelper.swift */; };
 		3EC35F2D200376A1008BDF95 /* SendViewController+Invitation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EC35F2C200376A1008BDF95 /* SendViewController+Invitation.swift */; };
 		3EC35F302003838E008BDF95 /* InvitationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EC35F2F2003838E008BDF95 /* InvitationTests.swift */; };
-		45262931B4C72A96C686C533 /* Pods_enzevalos_iphoneTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9B9CE43043CF806E1C02FCA /* Pods_enzevalos_iphoneTests.framework */; };
 		4706D65F225B7B6B00B3F1D3 /* ItunesHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4706D65E225B7B6B00B3F1D3 /* ItunesHandler.swift */; };
 		4706D661225CD21D00B3F1D3 /* ExportKeyHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4706D660225CD21D00B3F1D3 /* ExportKeyHelper.swift */; };
-		4706D663225CDFE200B3F1D3 /* TempKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4706D662225CDFE200B3F1D3 /* TempKey.swift */; };
 		4707091E2189BC3500DF71A3 /* plainThunderbird.eml in Resources */ = {isa = PBXBuildFile; fileRef = 470709172189BC3500DF71A3 /* plainThunderbird.eml */; };
 		470709262189C73900DF71A3 /* enc+signedInlineThunderbird.eml in Resources */ = {isa = PBXBuildFile; fileRef = 470709212189C73900DF71A3 /* enc+signedInlineThunderbird.eml */; };
 		470709272189C73900DF71A3 /* encThunderbird.eml in Resources */ = {isa = PBXBuildFile; fileRef = 470709222189C73900DF71A3 /* encThunderbird.eml */; };
@@ -43,6 +41,7 @@
 		472F398E1E251B8D009260FB /* MailAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F398D1E251B8D009260FB /* MailAddress.swift */; };
 		472F39901E252470009260FB /* CNMailAddressesExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F398F1E252470009260FB /* CNMailAddressesExtension.swift */; };
 		474054982244D7A9007CF83B /* MailServerConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 474054972244D7A9007CF83B /* MailServerConfigurationTest.swift */; };
+		474994022261E4E6000F8DA5 /* SimpleSendIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 474994012261E4E6000F8DA5 /* SimpleSendIcon.swift */; };
 		4756DE0E20402F8E00452288 /* invitationTextCensor.html in Resources */ = {isa = PBXBuildFile; fileRef = 4756DE0D20402F8E00452288 /* invitationTextCensor.html */; };
 		475B00331F7B9565006CDD41 /* SwiftPGP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00301F7B9565006CDD41 /* SwiftPGP.swift */; };
 		475B00341F7B9565006CDD41 /* Cryptography.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00311F7B9565006CDD41 /* Cryptography.swift */; };
@@ -80,6 +79,12 @@
 		479C649621F2139B00A01071 /* support_pk.asc in Resources */ = {isa = PBXBuildFile; fileRef = 479C649521F2139B00A01071 /* support_pk.asc */; };
 		479C649A21F45DAF00A01071 /* HideShowPasswordTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479C649821F45DAF00A01071 /* HideShowPasswordTextField.swift */; };
 		479C649B21F45DAF00A01071 /* PasswordToggleVisibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479C649921F45DAF00A01071 /* PasswordToggleVisibilityView.swift */; };
+		47A5D6D42294A8F60084F81D /* OnboardingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A5D6D32294A8F60084F81D /* OnboardingTest.swift */; };
+		47A5D6D92294B4EC0084F81D /* ObjectivePGP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47CEF4EC2052C3E600887CDB /* ObjectivePGP.framework */; };
+		47A5D6DA2294B50E0084F81D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 47F867E12052B48E00AA832F /* libz.tbd */; };
+		47A5D6DE2294B5480084F81D /* AppAuth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47A5D6DD2294B5480084F81D /* AppAuth.framework */; };
+		47A5D6E22294BF3B0084F81D /* TempKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A5D6E12294BF3A0084F81D /* TempKey.swift */; };
+		47A5D6E42294BFF50084F81D /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A5D6E32294BFF50084F81D /* Logger.swift */; };
 		47C22281218AFD6300BD2C2B /* AutocryptTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C22280218AFD6300BD2C2B /* AutocryptTest.swift */; };
 		47C22283218B02C700BD2C2B /* autocryptSimpleExample1.eml in Resources */ = {isa = PBXBuildFile; fileRef = 47C22282218B02C700BD2C2B /* autocryptSimpleExample1.eml */; };
 		47CD5AAA2012368D00E771A1 /* logging_pk.asc in Resources */ = {isa = PBXBuildFile; fileRef = 47CD5AA82012368D00E771A1 /* logging_pk.asc */; };
@@ -102,6 +107,7 @@
 		47F867E02052B47C00AA832F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47F867DF2052B47C00AA832F /* Security.framework */; };
 		47F867E22052B48E00AA832F /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 47F867E12052B48E00AA832F /* libz.tbd */; };
 		47F867E42052B49800AA832F /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 47F867E32052B49800AA832F /* libbz2.tbd */; };
+		7500EE9D4F3130671F5C1AE2 /* Pods_enzevalos_iphoneTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7977EA7012D8E98D186D5C60 /* Pods_enzevalos_iphoneTests.framework */; };
 		8428A8531F4369C0007649A5 /* Gamification.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8428A8521F4369C0007649A5 /* Gamification.storyboard */; };
 		8428A8551F4369CF007649A5 /* GamificationElements.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8428A8541F4369CF007649A5 /* GamificationElements.xcassets */; };
 		8428A85C1F436A05007649A5 /* ArrowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8428A8581F436A05007649A5 /* ArrowView.swift */; };
@@ -119,13 +125,11 @@
 		8428A8711F436A1E007649A5 /* GamificationStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8428A86D1F436A1E007649A5 /* GamificationStatusViewController.swift */; };
 		8428A8831F436AC9007649A5 /* GamificationDataUnitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8428A8561F4369EA007649A5 /* GamificationDataUnitTest.swift */; };
 		8428A8841F436ACC007649A5 /* GamificationElements.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8428A8541F4369CF007649A5 /* GamificationElements.xcassets */; };
-		9935BC866A86C4A4B9819F35 /* Pods_enzevalos_iphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AE42F42E91A1BFBF1D5BF6A /* Pods_enzevalos_iphone.framework */; };
-		9C1FA3A01B089C653802A88C /* Pods_enzevalos_iphoneUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48FB10FF406523D174F4202A /* Pods_enzevalos_iphoneUITests.framework */; };
 		A102AA8A1EDDB4F40024B457 /* videoOnboarding2.m4v in Resources */ = {isa = PBXBuildFile; fileRef = A102AA891EDDB4E80024B457 /* videoOnboarding2.m4v */; };
 		A1083A541E8BFEA6003666B7 /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1083A531E8BFEA6003666B7 /* Onboarding.swift */; };
 		A10DAA5721F37600005D8BBB /* IntroInfoButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10DAA5621F37600005D8BBB /* IntroInfoButton.swift */; };
 		A10DE4201EFAA2CE005E8189 /* FolderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10DE41F1EFAA2CE005E8189 /* FolderViewController.swift */; };
-		A111F6AD1FA77B170060AFDE /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = A111F6AC1FA77B170060AFDE /* Logger.swift */; };
+		A111F6AD1FA77B170060AFDE /* LoggerDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = A111F6AC1FA77B170060AFDE /* LoggerDetail.swift */; };
 		A1123E6A1DA682850069551C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1123E6C1DA682850069551C /* Localizable.strings */; };
 		A114E4321FACB23000E40243 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A114E4311FACB23000E40243 /* StringExtension.swift */; };
 		A12F91D821F3A99800AB0589 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12F91D721F3A99800AB0589 /* NSLayoutConstraintExtension.swift */; };
@@ -181,6 +185,8 @@
 		A1F992291DA7C9100073BF1B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1F9922B1DA7C9100073BF1B /* Main.storyboard */; };
 		A1F992391DA7DD2E0073BF1B /* InboxTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1F9923B1DA7DD2E0073BF1B /* InboxTableViewCell.xib */; };
 		A1FA44A721E10E1400DB02AC /* TravelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1FA44A621E10E1400DB02AC /* TravelHandler.swift */; };
+		AC4001CA169DC07A7A1E3AD3 /* Pods_enzevalos_iphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94EE54279AB591E0CAB8EFD8 /* Pods_enzevalos_iphone.framework */; };
+		D630501DC9A8FA6EAD919B96 /* Pods_enzevalos_iphoneUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF232CF5EE5EE7B9838EBDF4 /* Pods_enzevalos_iphoneUITests.framework */; };
 		F113C3851F30D06800E7F1D6 /* QRScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F113C3841F30D06800E7F1D6 /* QRScannerView.swift */; };
 		F113C38B1F3344C200E7F1D6 /* ViewControllerPannable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F113C38A1F3344C200E7F1D6 /* ViewControllerPannable.swift */; };
 		F119D2901E364B59001D732A /* AnimatedSendIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F119D28F1E364B59001D732A /* AnimatedSendIcon.swift */; };
@@ -188,7 +194,7 @@
 		F12041FD1DA409A5002E4940 /* ListViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12041FC1DA409A5002E4940 /* ListViewCell.swift */; };
 		F12060801DA540FE00F6EF37 /* RefreshControlExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120607F1DA540FE00F6EF37 /* RefreshControlExtension.swift */; };
 		F12060821DA552FC00F6EF37 /* MailHandlerDelegator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12060811DA552FC00F6EF37 /* MailHandlerDelegator.swift */; };
-		F120A7D31F7937BB006D5BF1 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
+		F120A7D31F7937BB006D5BF1 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
 		F12D8DBB2069422A0068788E /* About.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F12D8DBD2069422A0068788E /* About.storyboard */; };
 		F14239C11F30A99C00998A83 /* QRCodeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F14239C01F30A99C00998A83 /* QRCodeGenerator.swift */; };
 		F1737ACB2031D7D70000312B /* StudySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17FDFF2202C685800F7BA89 /* StudySettings.swift */; };
@@ -249,7 +255,6 @@
 		411EB2B85F99B48FFD36F966 /* Pods-enzevalos_iphoneTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneTests.debug.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneTests/Pods-enzevalos_iphoneTests.debug.xcconfig"; sourceTree = "<group>"; };
 		4706D65E225B7B6B00B3F1D3 /* ItunesHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItunesHandler.swift; sourceTree = "<group>"; };
 		4706D660225CD21D00B3F1D3 /* ExportKeyHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportKeyHelper.swift; sourceTree = "<group>"; };
-		4706D662225CDFE200B3F1D3 /* TempKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TempKey.swift; sourceTree = "<group>"; };
 		470709172189BC3500DF71A3 /* plainThunderbird.eml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = plainThunderbird.eml; sourceTree = "<group>"; };
 		470709212189C73900DF71A3 /* enc+signedInlineThunderbird.eml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "enc+signedInlineThunderbird.eml"; sourceTree = "<group>"; };
 		470709222189C73900DF71A3 /* encThunderbird.eml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = encThunderbird.eml; sourceTree = "<group>"; };
@@ -275,6 +280,7 @@
 		472F398D1E251B8D009260FB /* MailAddress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MailAddress.swift; sourceTree = "<group>"; };
 		472F398F1E252470009260FB /* CNMailAddressesExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CNMailAddressesExtension.swift; sourceTree = "<group>"; };
 		474054972244D7A9007CF83B /* MailServerConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailServerConfigurationTest.swift; sourceTree = "<group>"; };
+		474994012261E4E6000F8DA5 /* SimpleSendIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleSendIcon.swift; sourceTree = "<group>"; };
 		4756DE0D20402F8E00452288 /* invitationTextCensor.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = invitationTextCensor.html; path = Invitation/invitationTextCensor.html; sourceTree = "<group>"; };
 		475B00301F7B9565006CDD41 /* SwiftPGP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftPGP.swift; sourceTree = "<group>"; };
 		475B00311F7B9565006CDD41 /* Cryptography.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cryptography.swift; sourceTree = "<group>"; };
@@ -308,6 +314,12 @@
 		479C649521F2139B00A01071 /* support_pk.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = support_pk.asc; sourceTree = "<group>"; };
 		479C649821F45DAF00A01071 /* HideShowPasswordTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HideShowPasswordTextField.swift; sourceTree = "<group>"; };
 		479C649921F45DAF00A01071 /* PasswordToggleVisibilityView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordToggleVisibilityView.swift; sourceTree = "<group>"; };
+		47A5D6D32294A8F60084F81D /* OnboardingTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTest.swift; sourceTree = "<group>"; };
+		47A5D6D52294B4830084F81D /* GTMAppAuth.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = GTMAppAuth.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		47A5D6DB2294B5220084F81D /* libz.1.1.3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.1.1.3.tbd; path = usr/lib/libz.1.1.3.tbd; sourceTree = SDKROOT; };
+		47A5D6DD2294B5480084F81D /* AppAuth.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AppAuth.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		47A5D6E12294BF3A0084F81D /* TempKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TempKey.swift; sourceTree = "<group>"; };
+		47A5D6E32294BFF50084F81D /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
 		47B2318A1F0D458100961B28 /* enzevalos_iphone 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "enzevalos_iphone 2.xcdatamodel"; sourceTree = "<group>"; };
 		47C22280218AFD6300BD2C2B /* AutocryptTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocryptTest.swift; sourceTree = "<group>"; };
 		47C22282218B02C700BD2C2B /* autocryptSimpleExample1.eml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = autocryptSimpleExample1.eml; sourceTree = "<group>"; };
@@ -331,11 +343,10 @@
 		47F867DF2052B47C00AA832F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
 		47F867E12052B48E00AA832F /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
 		47F867E32052B49800AA832F /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; };
-		48FB10FF406523D174F4202A /* Pods_enzevalos_iphoneUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphoneUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-		4AE42F42E91A1BFBF1D5BF6A /* Pods_enzevalos_iphone.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphone.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		66E758F271CD65AB3E5FE7A7 /* Pods-enzevalos_iphoneUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneUITests.debug.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneUITests/Pods-enzevalos_iphoneUITests.debug.xcconfig"; sourceTree = "<group>"; };
 		6EBCCD02AD3B95D8317810E2 /* Pods-enzevalos_iphoneTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneTests.debug.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneTests/Pods-enzevalos_iphoneTests.debug.xcconfig"; sourceTree = "<group>"; };
 		796D16D79BED5D60B580E602 /* Pods-enzevalos_iphoneUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneUITests.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneUITests/Pods-enzevalos_iphoneUITests.release.xcconfig"; sourceTree = "<group>"; };
+		7977EA7012D8E98D186D5C60 /* Pods_enzevalos_iphoneTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphoneTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		8428A8521F4369C0007649A5 /* Gamification.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Gamification.storyboard; sourceTree = "<group>"; };
 		8428A8541F4369CF007649A5 /* GamificationElements.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = GamificationElements.xcassets; sourceTree = "<group>"; };
 		8428A8561F4369EA007649A5 /* GamificationDataUnitTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamificationDataUnitTest.swift; sourceTree = "<group>"; };
@@ -354,13 +365,14 @@
 		8428A86D1F436A1E007649A5 /* GamificationStatusViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamificationStatusViewController.swift; sourceTree = "<group>"; };
 		8B87EFB6CEAA31452F744015 /* Pods-enzevalos_iphoneUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneUITests.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneUITests/Pods-enzevalos_iphoneUITests.release.xcconfig"; sourceTree = "<group>"; };
 		91B6C9020C660BEA78FAEF28 /* Pods-enzevalos_iphone.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphone.debug.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone/Pods-enzevalos_iphone.debug.xcconfig"; sourceTree = "<group>"; };
+		94EE54279AB591E0CAB8EFD8 /* Pods_enzevalos_iphone.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphone.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		9A132EDE8BCA06ACDB505C22 /* Pods-enzevalos_iphoneUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneUITests.debug.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneUITests/Pods-enzevalos_iphoneUITests.debug.xcconfig"; sourceTree = "<group>"; };
 		9B3D62838C729BAC6832270A /* Pods-enzevalos_iphone-AdHoc.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphone-AdHoc.debug.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone-AdHoc/Pods-enzevalos_iphone-AdHoc.debug.xcconfig"; sourceTree = "<group>"; };
 		A102AA891EDDB4E80024B457 /* videoOnboarding2.m4v */ = {isa = PBXFileReference; lastKnownFileType = file; path = videoOnboarding2.m4v; sourceTree = "<group>"; };
 		A1083A531E8BFEA6003666B7 /* Onboarding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = "<group>"; };
 		A10DAA5621F37600005D8BBB /* IntroInfoButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroInfoButton.swift; sourceTree = "<group>"; };
 		A10DE41F1EFAA2CE005E8189 /* FolderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolderViewController.swift; sourceTree = "<group>"; };
-		A111F6AC1FA77B170060AFDE /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
+		A111F6AC1FA77B170060AFDE /* LoggerDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerDetail.swift; sourceTree = "<group>"; };
 		A1123E6B1DA682850069551C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
 		A1123E6D1DA682870069551C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
 		A114E4311FACB23000E40243 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
@@ -438,7 +450,7 @@
 		BC7D006B3B40A23E53B4F317 /* Pods-enzevalos_iphoneTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneTests.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneTests/Pods-enzevalos_iphoneTests.release.xcconfig"; sourceTree = "<group>"; };
 		C1F4458FC892EBE555836F55 /* Pods_enzevalos_iphone_AdHoc.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphone_AdHoc.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		C7733DFEFB7E7CFF38EC1665 /* Pods-enzevalos_iphoneTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneTests.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphoneTests/Pods-enzevalos_iphoneTests.release.xcconfig"; sourceTree = "<group>"; };
-		C9B9CE43043CF806E1C02FCA /* Pods_enzevalos_iphoneTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphoneTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		EF232CF5EE5EE7B9838EBDF4 /* Pods_enzevalos_iphoneUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphoneUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		F113C3841F30D06800E7F1D6 /* QRScannerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScannerView.swift; sourceTree = "<group>"; };
 		F113C38A1F3344C200E7F1D6 /* ViewControllerPannable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerPannable.swift; sourceTree = "<group>"; };
 		F119D28F1E364B59001D732A /* AnimatedSendIcon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatedSendIcon.swift; sourceTree = "<group>"; };
@@ -475,9 +487,9 @@
 				47F867E42052B49800AA832F /* libbz2.tbd in Frameworks */,
 				47F867E22052B48E00AA832F /* libz.tbd in Frameworks */,
 				47F867E02052B47C00AA832F /* Security.framework in Frameworks */,
-				F120A7D31F7937BB006D5BF1 /* (null) in Frameworks */,
+				F120A7D31F7937BB006D5BF1 /* BuildFile in Frameworks */,
 				472F396E1E14F384009260FB /* CoreData.framework in Frameworks */,
-				9935BC866A86C4A4B9819F35 /* Pods_enzevalos_iphone.framework in Frameworks */,
+				AC4001CA169DC07A7A1E3AD3 /* Pods_enzevalos_iphone.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -488,7 +500,7 @@
 				479B597A20691C0600B3944D /* libz.tbd in Frameworks */,
 				479B597920691BFB00B3944D /* libbz2.tbd in Frameworks */,
 				479B597820691BE400B3944D /* ObjectivePGP.framework in Frameworks */,
-				45262931B4C72A96C686C533 /* Pods_enzevalos_iphoneTests.framework in Frameworks */,
+				7500EE9D4F3130671F5C1AE2 /* Pods_enzevalos_iphoneTests.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -496,7 +508,10 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				9C1FA3A01B089C653802A88C /* Pods_enzevalos_iphoneUITests.framework in Frameworks */,
+				47A5D6DE2294B5480084F81D /* AppAuth.framework in Frameworks */,
+				47A5D6DA2294B50E0084F81D /* libz.tbd in Frameworks */,
+				47A5D6D92294B4EC0084F81D /* ObjectivePGP.framework in Frameworks */,
+				D630501DC9A8FA6EAD919B96 /* Pods_enzevalos_iphoneUITests.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -677,15 +692,18 @@
 		78280F99990BFF65543B7F0B /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				47A5D6DD2294B5480084F81D /* AppAuth.framework */,
+				47A5D6DB2294B5220084F81D /* libz.1.1.3.tbd */,
+				47A5D6D52294B4830084F81D /* GTMAppAuth.framework */,
 				47CEF4EC2052C3E600887CDB /* ObjectivePGP.framework */,
 				47F867E32052B49800AA832F /* libbz2.tbd */,
 				47F867E12052B48E00AA832F /* libz.tbd */,
 				47F867DF2052B47C00AA832F /* Security.framework */,
 				472F396D1E14F384009260FB /* CoreData.framework */,
-				4AE42F42E91A1BFBF1D5BF6A /* Pods_enzevalos_iphone.framework */,
-				C9B9CE43043CF806E1C02FCA /* Pods_enzevalos_iphoneTests.framework */,
-				48FB10FF406523D174F4202A /* Pods_enzevalos_iphoneUITests.framework */,
 				C1F4458FC892EBE555836F55 /* Pods_enzevalos_iphone_AdHoc.framework */,
+				94EE54279AB591E0CAB8EFD8 /* Pods_enzevalos_iphone.framework */,
+				7977EA7012D8E98D186D5C60 /* Pods_enzevalos_iphoneTests.framework */,
+				EF232CF5EE5EE7B9838EBDF4 /* Pods_enzevalos_iphoneUITests.framework */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -750,7 +768,8 @@
 		A111F6AB1FA77AF80060AFDE /* Logging */ = {
 			isa = PBXGroup;
 			children = (
-				A111F6AC1FA77B170060AFDE /* Logger.swift */,
+				A111F6AC1FA77B170060AFDE /* LoggerDetail.swift */,
+				47A5D6E32294BFF50084F81D /* Logger.swift */,
 				A18E7D761FBDE5D9002F7CC9 /* LoggingEventType.swift */,
 			);
 			name = Logging;
@@ -760,8 +779,8 @@
 			isa = PBXGroup;
 			children = (
 				475B00301F7B9565006CDD41 /* SwiftPGP.swift */,
-				4706D662225CDFE200B3F1D3 /* TempKey.swift */,
 				476801DA218436B600F7F259 /* Autocrypt.swift */,
+				47A5D6E12294BF3A0084F81D /* TempKey.swift */,
 				475B00311F7B9565006CDD41 /* Cryptography.swift */,
 				475B00321F7B9565006CDD41 /* CryptoObject.swift */,
 			);
@@ -862,6 +881,7 @@
 			isa = PBXGroup;
 			children = (
 				A135269B1D955BE000D3BFE1 /* enzevalos_iphoneUITests.swift */,
+				47A5D6D32294A8F60084F81D /* OnboardingTest.swift */,
 				A135269D1D955BE000D3BFE1 /* Info.plist */,
 			);
 			path = enzevalos_iphoneUITests;
@@ -988,6 +1008,7 @@
 			children = (
 				A1EB057F1D956851008659C1 /* SendViewController.swift */,
 				F119D28F1E364B59001D732A /* AnimatedSendIcon.swift */,
+				474994012261E4E6000F8DA5 /* SimpleSendIcon.swift */,
 				A1EB057D1D956848008659C1 /* VENDataDelegate.swift */,
 				A1EB05811D95685B008659C1 /* CollectionDataDelegate.swift */,
 				A1EB05831D956867008659C1 /* TableViewDataDelegate.swift */,
@@ -1078,9 +1099,9 @@
 				A13526711D955BDF00D3BFE1 /* Sources */,
 				A13526721D955BDF00D3BFE1 /* Frameworks */,
 				A13526731D955BDF00D3BFE1 /* Resources */,
-				1B3A7EC4B7EC43108D4CA42F /* [CP] Embed Pods Frameworks */,
 				47F867DB2052B33C00AA832F /* CopyFiles */,
 				47F867E52052B4B500AA832F /* ShellScript */,
+				3992B0CB6412E8526773B814 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -1268,11 +1289,13 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		1B3A7EC4B7EC43108D4CA42F /* [CP] Embed Pods Frameworks */ = {
+		3992B0CB6412E8526773B814 /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
+			inputFileListPaths = (
+			);
 			inputPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-enzevalos_iphone/Pods-enzevalos_iphone-frameworks.sh",
 				"${BUILT_PRODUCTS_DIR}/AppAuth/AppAuth.framework",
@@ -1287,6 +1310,8 @@
 				"${BUILT_PRODUCTS_DIR}/VENTokenField/VENTokenField.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
+			outputFileListPaths = (
+			);
 			outputPaths = (
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppAuth.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BZipCompression.framework",
@@ -1396,6 +1421,7 @@
 				8428A8651F436A11007649A5 /* BadgeCaseCollectionViewCell.swift in Sources */,
 				472F39811E1E5347009260FB /* Mail_Address+CoreDataClass.swift in Sources */,
 				A1EB05821D95685B008659C1 /* CollectionDataDelegate.swift in Sources */,
+				47A5D6E22294BF3B0084F81D /* TempKey.swift in Sources */,
 				47D1302B1F7CEE6D007B14DF /* DebugSettings.swift in Sources */,
 				A1EB05801D956851008659C1 /* SendViewController.swift in Sources */,
 				479C649B21F45DAF00A01071 /* PasswordToggleVisibilityView.swift in Sources */,
@@ -1420,6 +1446,7 @@
 				A1735DFA205AB88500B336DB /* SendViewState.swift in Sources */,
 				475B00331F7B9565006CDD41 /* SwiftPGP.swift in Sources */,
 				477548E421F77BA0000B22A8 /* StudyParameterProtocol.swift in Sources */,
+				47A5D6E42294BFF50084F81D /* Logger.swift in Sources */,
 				3EB4FAA420120096001D0625 /* DialogOption.swift in Sources */,
 				F14239C11F30A99C00998A83 /* QRCodeGenerator.swift in Sources */,
 				478154A921FF3FF400A931EC /* Invitation.swift in Sources */,
@@ -1467,8 +1494,7 @@
 				A1EB05961D956939008659C1 /* InboxTableViewCell.swift in Sources */,
 				47F79240203492E3005E7DB6 /* KeyRecord+CoreDataClass.swift in Sources */,
 				A1083A541E8BFEA6003666B7 /* Onboarding.swift in Sources */,
-				A111F6AD1FA77B170060AFDE /* Logger.swift in Sources */,
-				4706D663225CDFE200B3F1D3 /* TempKey.swift in Sources */,
+				A111F6AD1FA77B170060AFDE /* LoggerDetail.swift in Sources */,
 				A13526791D955BDF00D3BFE1 /* AppDelegate.swift in Sources */,
 				476916A2216B86CF00491527 /* EnzevalosContact+CoreDataClass.swift in Sources */,
 				A1ECE54B1EFBE7ED0009349F /* FolderCell.swift in Sources */,
@@ -1489,6 +1515,7 @@
 				A198D2292056B384004CC838 /* SendViewDelegate.swift in Sources */,
 				479011492289975D0057AB04 /* NoSecIconStyleKit.swift in Sources */,
 				F12060821DA552FC00F6EF37 /* MailHandlerDelegator.swift in Sources */,
+				474994022261E4E6000F8DA5 /* SimpleSendIcon.swift in Sources */,
 				A12F91D821F3A99800AB0589 /* NSLayoutConstraintExtension.swift in Sources */,
 				A18E7D771FBDE5D9002F7CC9 /* LoggingEventType.swift in Sources */,
 				F1984D741E1E92B300804E1E /* LabelStyleKit.swift in Sources */,
@@ -1525,6 +1552,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				47A5D6D42294A8F60084F81D /* OnboardingTest.swift in Sources */,
 				A135269C1D955BE000D3BFE1 /* enzevalos_iphoneUITests.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1898,6 +1926,10 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 66E758F271CD65AB3E5FE7A7 /* Pods-enzevalos_iphoneUITests.debug.xcconfig */;
 			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)_workspace",
+				);
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				INFOPLIST_FILE = enzevalos_iphoneUITests/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -1917,6 +1949,10 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 8B87EFB6CEAA31452F744015 /* Pods-enzevalos_iphoneUITests.release.xcconfig */;
 			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)_workspace",
+				);
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				INFOPLIST_FILE = enzevalos_iphoneUITests/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
diff --git a/enzevalos_iphone.xcodeproj/xcshareddata/xcschemes/enzevalos_iphone.xcscheme b/enzevalos_iphone.xcodeproj/xcshareddata/xcschemes/enzevalos_iphone.xcscheme
index 0976c58d9bd61995247832d1f92617f2a0b2b0be..eab64b2c429453d2ca9a20593c611ac6b6f0555d 100644
--- a/enzevalos_iphone.xcodeproj/xcshareddata/xcschemes/enzevalos_iphone.xcscheme
+++ b/enzevalos_iphone.xcodeproj/xcshareddata/xcschemes/enzevalos_iphone.xcscheme
@@ -26,6 +26,7 @@
       buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      codeCoverageEnabled = "YES"
       shouldUseLaunchSchemeArgsEnv = "YES">
       <Testables>
          <TestableReference
@@ -64,6 +65,11 @@
          </BuildableReference>
       </MacroExpansion>
       <AdditionalOptions>
+         <AdditionalOption
+            key = "NSZombieEnabled"
+            value = "YES"
+            isEnabled = "YES">
+         </AdditionalOption>
       </AdditionalOptions>
    </TestAction>
    <LaunchAction
diff --git a/enzevalos_iphone/AnimatedSendIcon.swift b/enzevalos_iphone/AnimatedSendIcon.swift
index 79a93830e4eccd4a59a7c43adb25663c317361ae..196d76bc2940c49d1270665f537073322e1c365a 100644
--- a/enzevalos_iphone/AnimatedSendIcon.swift
+++ b/enzevalos_iphone/AnimatedSendIcon.swift
@@ -22,7 +22,7 @@
 import Foundation
 import UIKit
 
-class AnimatedSendIcon: UIView {
+class AnimatedSendIcon: UIView, SendIcon {
     var isPostcardOnTop = false
     var square = UIImageView(image: StudySettings.securityIndicator.imageOfSecureIndicator(background: true, open: false))
     var square2 = UIImageView(image: StudySettings.securityIndicator.imageOfInsecureIndicator(background: true))
diff --git a/enzevalos_iphone/AppDelegate.swift b/enzevalos_iphone/AppDelegate.swift
index 69dd886f71b21f48eb8bdb4a3015bbac062cbf57..47b756d4a87e9f6c2f098164a494567ce4d5aede 100644
--- a/enzevalos_iphone/AppDelegate.swift
+++ b/enzevalos_iphone/AppDelegate.swift
@@ -50,7 +50,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         //StudySettings.firstMail()
         if (!UserDefaults.standard.bool(forKey: "launchedBefore")) {
 //            Logger.queue.async(flags: .barrier) {
-                Logger.log(startApp: true)
+               // Logger.log(startApp: true)
 //            }
             // Remove Google Auth token from keychain
             GTMKeychain.removePasswordFromKeychain(forName: "googleOAuthCodingKey")
@@ -67,7 +67,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
             
         } else {
             AddressHandler.updateCNContacts()
-            Logger.log(startApp: false)
+           // Logger.log(startApp: false)
             presentInboxViewController()
         }
         NotificationCenter.default.addObserver(
@@ -114,7 +114,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     }
     
     func googleLogin(vc: UIViewController) {
-        Logger.log(onboardingState: "oAuth")
+        // Logger.log(onboardingState: .GoogleLogIn)
+        Logger.log(onboardingState: .GoogleLogIn, duration: 0)
         if self.currentReachabilityStatus == .notReachable {
             if showAlertNoConnection {
                 let alert = UIAlertController(title: NSLocalizedString("Error.noInternet.Title", comment: ""), message: NSLocalizedString("Error.noInternet.Message", comment: ""), preferredStyle: .alert)
@@ -215,7 +216,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     }
 
     func onboardingDone() {
-        Logger.log(onboardingState: "done")
+        Logger.log(onboardingState: .Finish, duration: 0)
         UserDefaults.standard.set(true, forKey: "launchedBefore")
         self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
         presentInboxViewController()
@@ -352,6 +353,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     func hasNewMails(_ newMails: UInt32, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void){
         let duration = Date().timeIntervalSince(start)
         Logger.log(backgroundFetch: newMails, duration: duration)
+        
+        guard newMails > 0 else {
+            UIApplication.shared.applicationIconBadgeNumber = 0
+            completionHandler(.noData)
+            return
+        }
         let mails = newMails - 1
         if mails > 0 {
             UIApplication.shared.applicationIconBadgeNumber = Int(mails)
diff --git a/enzevalos_iphone/Autocrypt.swift b/enzevalos_iphone/Autocrypt.swift
index 651569507a6e104ca765907fbbb5896e284cd906..e2a4b5d17e12688ebe8070e885447d8eea664995 100644
--- a/enzevalos_iphone/Autocrypt.swift
+++ b/enzevalos_iphone/Autocrypt.swift
@@ -110,7 +110,7 @@ class Autocrypt {
             if let key = pgp.exportKey(id: id, isSecretkey: false, autocrypt: true) {
                 var string = "\(ADDR)=" + adr
                 string = string + "; \(ENCRYPTION)=\(encPref.name)"
-                string = string + "; \(KEY)= \n" + key
+                string = string + "; \(KEY)=" + key
                 builder.header.setExtraHeaderValue(string, forName: AUTOCRYPTHEADER)
             }
         }
diff --git a/enzevalos_iphone/CryptoObject.swift b/enzevalos_iphone/CryptoObject.swift
index ebc237dc43a4466aa00b6c7335db5f535c7885df..a295183e46b763cef459c77f4cd58a1305446a1a 100644
--- a/enzevalos_iphone/CryptoObject.swift
+++ b/enzevalos_iphone/CryptoObject.swift
@@ -3,30 +3,31 @@
 //  ObjectivePGP
 //
 //  Created by Oliver Wiese on 25.09.17.
-//  Copyright © 2017 Marcin Krzyżanowski. All rights reserved.
 //
 
 import Foundation
 
-/* enum SignatureState: Int16 {
-    case NoSignature = 0
-    case NoPublicKey = -1
-    case InvalidSignature = -2
-    case ValidSignature = 1
-}
-
-enum EncryptionState: Int16 {
-    case NoEncryption = 0
-    case UnableToDecrypt = -1
-    case ValidEncryptedWithOldKey = 1
-    case ValidedEncryptedWithCurrentKey = 2
-} */
-
 enum SignatureState: Int16 {
     case NoSignature = 0
     case NoPublicKey = 1
     case InvalidSignature = -1
     case ValidSignature = 2
+    
+    var name: String {
+        get {
+            switch self {
+            case .NoSignature:
+                return "NoSignature"
+            case .NoPublicKey:
+                return "NoPublicKey"
+            case .InvalidSignature:
+                return "InvalidSignature"
+            case .ValidSignature:
+                return "ValidSignature"
+            }
+        }
+    }
+    public static let allStates = [NoSignature, NoPublicKey, InvalidSignature, ValidSignature]
 }
 
 enum EncryptionState: Int16 {
@@ -34,6 +35,22 @@ enum EncryptionState: Int16 {
     case UnableToDecrypt = 1
     case ValidEncryptedWithOldKey = 2
     case ValidedEncryptedWithCurrentKey = 3
+    
+    var name: String {
+        get {
+            switch self {
+            case .NoEncryption:
+                return "NoEnc"
+            case .UnableToDecrypt:
+                return "UnableToDec"
+            case .ValidedEncryptedWithCurrentKey:
+                return "DecWithPrefKey"
+            case .ValidEncryptedWithOldKey:
+                return "DecWithNoPrefKey"
+            }
+        }
+    }
+    public static let allStates = [NoEncryption, UnableToDecrypt, ValidEncryptedWithOldKey, ValidedEncryptedWithCurrentKey]
 }
 
 public enum CryptoScheme {
diff --git a/enzevalos_iphone/DataHandler.swift b/enzevalos_iphone/DataHandler.swift
index 40310396723312aa9ffbdbc9ed79d9cdb9ce1c42..effea58adc6e5cd4b8867d97bfa57e14f2c8b183 100644
--- a/enzevalos_iphone/DataHandler.swift
+++ b/enzevalos_iphone/DataHandler.swift
@@ -377,11 +377,11 @@ class DataHandler {
             search.addToMailaddresses(adr)
             pk = search
             if Logger.logging {
-                var importChannel = "autocrypt"
+                var importChannel = LogData.TransferType.autocrypt
                 if newGenerated {
-                    importChannel = "generated"
+                    importChannel = LogData.TransferType.generated
                 } else if !autocrypt {
-                    importChannel = "attachment"
+                    importChannel = .mail
                 }
                 Logger.log(discover: pk.keyID, mailAddress: adr, importChannel: importChannel, knownPrivateKey: DataHandler.handler.findSecretKeys().map { ($0.keyID ?? "") == keyID }.reduce(false, { $0 || $1 }), knownBefore: true)
             }
@@ -410,11 +410,11 @@ class DataHandler {
                 save(during: "new pk")
             }
             if Logger.logging {
-                var importChannel = "autocrypt"
+                var importChannel = LogData.TransferType.autocrypt
                 if newGenerated {
-                    importChannel = "generated"
+                    importChannel = .generated
                 } else if !autocrypt {
-                    importChannel = "attachment"
+                    importChannel = .mail
                 }
                 Logger.log(discover: pk.keyID, mailAddress: adr, importChannel: importChannel, knownPrivateKey: DataHandler.handler.findSecretKeys().map { ($0.keyID ?? "") == keyID }.reduce(false, { $0 || $1 }), knownBefore: false)
             }
@@ -431,6 +431,7 @@ class DataHandler {
         if saveKey {
             save(during: "new PK")
         }
+        adr.addToKeys(key: pk)
         return pk
     }
 
@@ -469,6 +470,13 @@ class DataHandler {
         }
         return [SecretKey]()
     }
+    
+    func findPublicKeys() -> [PersistentKey] {
+        if let result = findAll("PersistentKey") {
+            return result as! [PersistentKey]
+        }
+        return [PersistentKey]()
+    }
 
     func findSecretKey(keyID: String) -> SecretKey? {
         if let result = find("SecretKey", type: "keyID", search: keyID) {
@@ -516,6 +524,14 @@ class DataHandler {
 
     private func findAll(_ entityName: String) -> [AnyObject]? {
         let fReq: NSFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
+        if entityName == "KeyRecord" {
+            let sortDescriptor = NSSortDescriptor(key: "newestDate", ascending: false)
+            fReq.sortDescriptors = [sortDescriptor]
+        }
+        else if entityName == "PersistentMail" {
+            let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
+            fReq.sortDescriptors = [sortDescriptor]
+        }
         let result: [AnyObject]?
         do {
             result = try self.managedObjectContext.fetch(fReq)
@@ -654,6 +670,25 @@ class DataHandler {
         }
         return nil
     }
+    
+    func findMailAddress(withKey: Bool) -> [Mail_Address] {
+        let fReq: NSFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Mail_Address")
+        if withKey {
+            fReq.predicate = NSPredicate(format: "keys.@count > 0")
+        }
+        else {
+            fReq.predicate = NSPredicate(format: "keys.@count == 0")
+        }
+        do {
+            let result = try self.managedObjectContext.fetch(fReq)
+            if let res = result as? [Mail_Address] {
+                return res
+            }
+        } catch _ as NSError {
+           print("error")
+        }
+        return [Mail_Address]()
+    }
 
 
     func getMailAddressByMCOAddress(_ address: MCOAddress, temporary: Bool) -> MailAddress {
@@ -781,6 +816,27 @@ class DataHandler {
         }
         return nil
     }
+    
+    func removeAttachments() -> Int {
+        var safedStorage = 0
+        var counterAttachments = 0
+        var counterManipulatedMails = 0
+        for m in getAllPersistentMails() {
+            if m.hasAttachment {
+                counterManipulatedMails  += 1
+                if let atts = m.attachments {
+                    counterAttachments += atts.count
+                    for x in atts {
+                        if let data = x as? Attachment {
+                            safedStorage += data.data?.count ?? 0
+                            m.removeFromAttachments(data)
+                        }
+                    }
+                }
+            }
+        }
+        return safedStorage
+    }
     // -------- End handle to, cc, from addresses --------
 
     func createMail(_ uid: UInt64, sender: MCOAddress?, receivers: [MCOAddress], cc: [MCOAddress], time: Date, received: Bool, subject: String, body: String?, readableAttachments: Set<TempAttachment> = Set<TempAttachment>(), flags: MCOMessageFlag, record: KeyRecord?, autocrypt: Autocrypt?, decryptedData: CryptoObject?, folderPath: String, secretKey: String?, references: [String] = [], mailagent: String? = nil, messageID: String? = nil, encryptedBody: String?, storeEncrypted: Bool = false) -> PersistentMail? {
@@ -794,7 +850,7 @@ class DataHandler {
             mails = tmpMails
         }
 
-        if finding == nil || finding!.count == 0 || mails.filter({ $0.folder.path == folderPath && $0.uidvalidity == myfolder.uidvalidity }).count == 0 || uid == 0{
+        if finding == nil || finding!.count == 0 || mails.filter({ $0.folder.path == folderPath && $0.uidvalidity == myfolder.uidvalidity }).count == 0 || uid == 0 || !myfolder.uids.contains(uid) {
             // create new mail object
             mail = NSEntityDescription.insertNewObject(forEntityName: "PersistentMail", into: managedObjectContext) as! PersistentMail
 
@@ -924,6 +980,14 @@ class DataHandler {
         }
         record.addToPersistentMails(mail)
         mail.folder.addToKeyRecords(record)
+        if record.newestDate == nil {
+            record.newestDate = mail.date
+        }
+        if let date = record.newestDate, date.timeIntervalSince(mail.date) < 0 {
+            // We should update our records...
+            record.newestDate = mail.date
+        }
+        
         for at in readableAttachments{
             _ = self.newAttachment(temp: at, mail: mail)
         }
@@ -941,7 +1005,6 @@ class DataHandler {
             }
         }
         return adrs
-
     }
 
     func getContacts() -> [EnzevalosContact] {
@@ -973,9 +1036,12 @@ class DataHandler {
     
     func getAllKeyRecords() -> [KeyRecord] {
         var result: [KeyRecord] = []
-        if let folders = findAll("Folder") as? [Folder] {
-            for folder in folders {
-                result += folder.records
+        if let records = findAll("KeyRecord") as? [KeyRecord] {
+            result = records.filter{
+                if let mails = $0.persistentMails {
+                    return mails.count != 0
+                }
+                return false
             }
         }
         return result
diff --git a/enzevalos_iphone/Folder+CoreDataClass.swift b/enzevalos_iphone/Folder+CoreDataClass.swift
index 2762bcf51c86f82cc6dcd7a58d704609ce147091..eb00228747ca780a931824839abb5765c099f305 100644
--- a/enzevalos_iphone/Folder+CoreDataClass.swift
+++ b/enzevalos_iphone/Folder+CoreDataClass.swift
@@ -40,9 +40,7 @@ public class Folder: NSManagedObject {
 
         get {
             let ids = MCOIndexSet()
-            for m in mailsOfFolder {
-                ids.add(m.uid)
-            }
+            mailsOfFolder.forEach{ids.add($0.uid)}
             return ids
         }
     }
@@ -51,12 +49,11 @@ public class Folder: NSManagedObject {
 
     var records: [KeyRecord] {
         get {
-            if let keyRecords = keyRecords as? Set<KeyRecord> {
-                return Array(keyRecords).sorted()
+            guard keyRecords != nil && keyRecords?.count ?? 0 > 0 else {
+                return []
             }
-            return []
+            return DataHandler.handler.getAllKeyRecords()
         }
-
     }
 
 
@@ -86,60 +83,4 @@ public class Folder: NSManagedObject {
             return folders
         }
     }
-
-    /*
-    func updateRecords(mail: PersistentMail){
-        if let reccords = storedRecords{
-            if reccords.count <= 2{
-                updateRecords()
-                return
-            }
-            var founded = false
-            for i in 1..<reccords.count {
-                let r = reccords[i]
-                if r.match(mail: mail){
-                    founded = true
-                    if r.mailsInFolder(folder: self).first == mail {
-                        if reccords[i-1] > r {
-                            storedRecords?.sort()
-                            break
-                        }
-                    }
-                }
-            }
-            if !founded && mail.folder == self{
-                if mail.isSecure && mail.keyID != nil{
-                    let record = KeyRecord(keyID: mail.keyID!, folder: self)
-                    if !(storedRecords?.contains(record))!{
-                        if record.mails.count > 0{
-                            storedRecords?.append(record)
-                        }
-                    }
-                }
-                else {
-                    let record = KeyRecord(contact: mail.from.contact!, folder: self)
-                    if !(storedRecords?.contains(record))!{
-                        if record.mails.count > 0{
-                            storedRecords?.append(record)
-                        }
-                    }
-                }
-                storedRecords?.sort()
-            }
-        }
-        else{
-            if mail.folder == self{
-                storedRecords = [KeyRecord]()
-                if mail.isSecure && mail.keyID != nil{
-                    let record = KeyRecord(keyID: mail.keyID!, folder: self)
-                    storedRecords?.append(record)
-                }
-                else{
-                    let record = KeyRecord(contact: mail.from.contact!, folder: self)
-                    storedRecords?.append(record)
-                }
-            }
-        }
-    }
- */
 }
diff --git a/enzevalos_iphone/Folder+CoreDataProperties.swift b/enzevalos_iphone/Folder+CoreDataProperties.swift
index f83885de0188b633bfc81164cc6d8d0dcee317a3..a1f45577d6d09965f49de8b8b165a177a8ead9b8 100644
--- a/enzevalos_iphone/Folder+CoreDataProperties.swift
+++ b/enzevalos_iphone/Folder+CoreDataProperties.swift
@@ -83,6 +83,29 @@ extension Folder {
             return text!
         }
     }
+    
+    public var minID: UInt64 {
+        set {
+            self.willChangeValue(forKey: "minUID")
+            self.setPrimitiveValue(NSDecimalNumber.init(value: newValue as UInt64), forKey: "minUID")
+            self.didChangeValue(forKey: "minUID")
+        }
+        get {
+            self.willAccessValue(forKey: "minUID")
+            let id = (self.primitiveValue(forKey: "minUID") as? NSDecimalNumber)?.uint64Value
+            self.didAccessValue(forKey: "minUID")
+            if id == nil {
+                var min = maxID
+                mailsOfFolder.forEach{
+                    if $0.uid < min {
+                        min = $0.uid
+                    }
+                }
+                return min
+            }
+            return id!
+        }
+    }
 }
 
 // MARK: Generated accessors for mails
diff --git a/enzevalos_iphone/FolderViewController.swift b/enzevalos_iphone/FolderViewController.swift
index 115a327b1e41c98fe483d243d75fff969496b1e7..c7dee764c99661711fc8a675850ae78e19c96454 100644
--- a/enzevalos_iphone/FolderViewController.swift
+++ b/enzevalos_iphone/FolderViewController.swift
@@ -22,6 +22,7 @@ import UIKit
 
 class FolderViewController: UITableViewController {
 
+    var mailHandler = AppDelegate.getAppDelegate().mailHandler
     var folders: [Folder] = []
 
     var isFirstFolderViewController = true
@@ -54,7 +55,7 @@ class FolderViewController: UITableViewController {
         if let thisFolder = presentedFolder {
             navigationItem.title = UserManager.convertToFrontendFolderPath(from: thisFolder.name)
             refreshControl?.beginRefreshing()
-            AppDelegate.getAppDelegate().mailHandler.updateFolder(folder: thisFolder, completionCallback: endRefreshing)
+            mailHandler.updateFolder(folder: thisFolder, completionCallback: endRefreshing)
             folders = thisFolder.subfolders.sorted()
         }
         NotificationCenter.default.addObserver(forName: Notification.Name.NSManagedObjectContextDidSave, object: nil, queue: nil, using: {
@@ -203,7 +204,7 @@ class FolderViewController: UITableViewController {
         lastUpdateText = NSLocalizedString("Updating", comment: "Getting new data")
         if let thisFolder = presentedFolder {
             refreshControl?.beginRefreshing()
-            AppDelegate.getAppDelegate().mailHandler.updateFolder(folder: thisFolder, completionCallback: endRefreshing(_:))
+            mailHandler.updateFolder(folder: thisFolder, completionCallback: endRefreshing(_:))
         } else {
             DataHandler.handler.callForFolders(done: endRefreshing)
         }
diff --git a/enzevalos_iphone/ItunesHandler.swift b/enzevalos_iphone/ItunesHandler.swift
index ae20a41e8e07700e1641e5a3d6a98d514ab98e67..4ffabfb176e9eed0fb86660b04dfeb3a3f3a0163 100644
--- a/enzevalos_iphone/ItunesHandler.swift
+++ b/enzevalos_iphone/ItunesHandler.swift
@@ -48,7 +48,7 @@ class ItunesKeyHandling {
         get {
             var keys: [TempKey] = []
             for url in keyURL {
-                if let file = try? FileHandle(forReadingFrom: url){
+                if let file = try? FileHandle(forReadingFrom: url) {
                     let data = file.readDataToEndOfFile()
                     var creationDate = Date()
                     if let attrs = try? fileManager.attributesOfItem(atPath: url.path) as NSDictionary, let date = attrs.fileCreationDate() {
@@ -68,7 +68,6 @@ class ItunesKeyHandling {
             var keys: [URL] = []
             let dirs = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
             for url in dirs {
-                print(url)
                 if let files = try? fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: .skipsHiddenFiles) {
                     let keyFiles = files.filter{ $0.pathExtension == "asc"}
                     keys.append(contentsOf: keyFiles)
diff --git a/enzevalos_iphone/KeyRecord+CoreDataProperties.swift b/enzevalos_iphone/KeyRecord+CoreDataProperties.swift
index 28689eed9dfa8202295ccc48886e46b088bc351e..ab33fe7478d78c954c12133cdac00f53ae28ecda 100644
--- a/enzevalos_iphone/KeyRecord+CoreDataProperties.swift
+++ b/enzevalos_iphone/KeyRecord+CoreDataProperties.swift
@@ -32,6 +32,7 @@ extension KeyRecord {
     @NSManaged public var folder: Folder?
     @NSManaged public var key: PersistentKey?
     @NSManaged public var persistentMails: NSSet?
+    @NSManaged public var newestDate: Date?
 
     var activeKey: PersistentKey? {
         get {
diff --git a/enzevalos_iphone/Logger.swift b/enzevalos_iphone/Logger.swift
index edec43b402338f04c03f58515e5aed63bd42b49a..9a34558dedee86d5dbf8270368648a94d5d1dba9 100644
--- a/enzevalos_iphone/Logger.swift
+++ b/enzevalos_iphone/Logger.swift
@@ -1,40 +1,21 @@
 //
-//  Logger.swift
+//  LoggerFirstStudy.swift
 //  enzevalos_iphone
 //
-//  Created by jakobsbode on 25.10.17.
-//  Copyright © 2018 fu-berlin.
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+//  Created by Oliver Wiese on 09.05.19.
+//  Copyright © 2019 fu-berlin. All rights reserved.
 //
 
 import Foundation
 
-class Logger {
-
-    static var logging = false //StudySettings.studyMode
-
-    static let queue = DispatchQueue(label: "logging", qos: .background)
-
-    static let defaultFileName = "log.json"
+class Logger{
+    
+    static var logging = StudySettings.studyMode
     static let loggingInterval = 21600 //60*60*6 seconds = 6 hours
     static let resendInterval = 5 * 60
     static let logReceiver = LOGGING_MAIL_ADR
-
+    
     static var nextDeadline = (UserManager.loadUserValue(Attribute.nextDeadline) as? Date) ?? Date()
-
-    static var studyID = StudySettings.studyID //identifies the participant in the study
-
     
     
     static fileprivate func sendCheck() {
@@ -46,903 +27,635 @@ class Logger {
             sendLog()
         }
     }
-
-    static fileprivate func plainLogDict() -> [String: Any] {
-        var fields: [String: Any] = [:]
-        let now = Date()
-        fields["timestamp"] = now.description
-        fields["lang"] = Locale.current.languageCode
-        return fields
-    }
-
-    static fileprivate func dictToJSON(fields: [String: Any]) -> String {
-        do {
-            let jsonData = try JSONSerialization.data(withJSONObject: fields)
-            if let json = String(data: jsonData, encoding: String.Encoding.utf8) {
-                return json
-            }
-            return ""
-        } catch {
-            return "{\"error\":\"json conversion failed\"}"
-        }
-    }
-
+    
     static func log(setupStudy studypara: [StudyParameterProtocol.Type], alreadyRegistered: Bool) {
         if !logging {
             return
         }
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.setupStudy.rawValue
-        
-        //event["language"] =
-       
-        for para in studypara{
-            event[para.name] = para.load().value
-        }
-        event["alreadyRegistered"] = alreadyRegistered
-        saveToDisk(json: dictToJSON(fields: event))
         sendCheck()
     }
-
+    
     static func log(startApp onboarding: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.appStart.rawValue
-        event["onboarding"] = onboarding
-        saveToDisk(json: dictToJSON(fields: event))
+        
+        LogData.newSimpleEvent(event: .newSession)
         sendCheck()
     }
-
+    
     static func log(terminateApp: Void) {
         if !logging {
             return
         }
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.appTerminate.rawValue
-        saveToDisk(json: dictToJSON(fields: event))
     }
-
+    
     static func log(background goto: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.appBackground.rawValue
-        event["going to"] = goto //true -> goto background; false -> comming from background
-        saveToDisk(json: dictToJSON(fields: event))
+        if !goto {
+            LogData.newSimpleEvent(event: .newSession)
+        }
         sendCheck()
     }
-
-    static func log(onboardingState onboardingSection: String) {
+    
+    
+    static func log(onboardingState onboardingSection: IntroState, duration: Double) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.onboardingState.rawValue
-        event["onboardingSection"] = onboardingSection
-        saveToDisk(json: dictToJSON(fields: event))
+        LogData.viewOnboardingSlide(type: onboardingSection, duration: duration)
         sendCheck()
     }
-
+    
     static func log(onboardingPageTransition from: Int, to: Int, onboardingSection: String) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.onboardingPageTransition.rawValue
-        event["from"] = from
-        event["to"] = to
-        event["onboardingSection"] = onboardingSection
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(contactViewOpen keyRecord: KeyRecord?, otherRecords: [KeyRecord]?, isUser: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.contactViewOpen.rawValue
-
-        if let keyRecord = keyRecord {
-            if let keyID = keyRecord.keyID {
-                event["keyID"] = resolve(keyID: keyID)
-            } else {
-                event["keyID"] = "nil"
-            }
-            event["mailaddresses"] = resolve(mailAddresses: keyRecord.addresses)
-        }
-        event["isUser"] = isUser
-        if isUser {
-            let (contact, mail) = GamificationData.sharedInstance.getSecureProgress()
-            event["gamificationContact"] = contact
-            event["gamificationMail"] = mail
-        }
-        event["numberOfOtherRecords"] = (otherRecords ?? []).count
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(badgeCaseViewOpen badges: [Badges]) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.badgeCaseViewOpen.rawValue
-
-        var achievedBadges: [String] = []
-        var missingBadges: [String] = []
-
-        for badge in badges {
-            if badge.isAchieved() {
-                achievedBadges.append(badge.displayName)
-            } else {
-                missingBadges.append(badge.displayName)
-            }
-        }
-
-        event["achievedBadges"] = achievedBadges
-        event["missingBadges"] = missingBadges
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(badgeCaseViewClose badges: [Badges]) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.badgeCaseViewClose.rawValue
-
-        var achievedBadges: [String] = []
-        var missingBadges: [String] = []
-
-        for badge in badges {
-            if badge.isAchieved() {
-                achievedBadges.append(badge.displayName)
-            } else {
-                missingBadges.append(badge.displayName)
-            }
-        }
-
-        event["achievedBadges"] = achievedBadges
-        event["missingBadges"] = missingBadges
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(contactViewClose keyRecord: KeyRecord?, otherRecords: [KeyRecord]?, isUser: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.contactViewClose.rawValue
-
-        if let keyRecord = keyRecord {
-            if let keyID = keyRecord.keyID {
-                event["keyID"] = resolve(keyID: keyID)
-            } else {
-                event["keyID"] = "nil"
-            }
-            event["mailaddresses"] = resolve(mailAddresses: keyRecord.addresses)
-        }
-        event["isUser"] = isUser
-        if isUser {
-            let (contact, mail) = GamificationData.sharedInstance.getSecureProgress()
-            event["gamificationContact"] = contact
-            event["gamificationMail"] = mail
-        }
-        event["numberOfOtherRecords"] = (otherRecords ?? []).count
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(keyViewOpen keyID: String) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.keyViewOpen.rawValue
-        event["keyID"] = resolve(keyID: keyID)
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
+        LogData.newSimpleEvent(event: .keyDetailsView)
+        
     }
-
+    
     static func log(keyViewClose keyID: String, secondsOpened: Int) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.keyViewClose.rawValue
-        event["keyID"] = resolve(keyID: keyID)
-        event["opened for seconds"] = secondsOpened
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(exportKeyViewOpen view: Int) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.exportKeyViewOpen.rawValue
-        event["view"] = view
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(exportKeyViewClose view: Int) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.exportKeyViewClose.rawValue
-        event["view"] = view
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(exportKeyViewButton send: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.exportKeyViewClose.rawValue
         if send {
-            event["case"] = "sendMail"
-        } else {
-            event["case"] = "deletePasscode"
+            LogData.exportKey(keyType: .secretKey, transferType: .autocrypt)
         }
-
-        saveToDisk(json: dictToJSON(fields: event))
         sendCheck()
     }
-
+    
     static func log(importPrivateKeyPopupOpen mail: PersistentMail?) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.importPrivateKeyPopupOpen.rawValue
-        if let mail = mail {
-            event = extract(from: mail, event: event)
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(importPrivateKeyPopupClose mail: PersistentMail?, doImport: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.importPrivateKeyPopupClose.rawValue
-        event["doImport"] = doImport
-        if let mail = mail {
-            event = extract(from: mail, event: event)
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(importPrivateKey mail: PersistentMail?, success: Bool) {
         if !logging {
             return
         }
+        LogData.importKey(keyType: .secretKey, transferType: .mail, known: false)
 
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.importPrivateKey.rawValue
-        event["success"] = success
-        if let mail = mail {
-            event = extract(from: mail, event: event)
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
         sendCheck()
     }
-
+    
     static func log(sendViewOpen mail: EphemeralMail?) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.sendViewOpen.rawValue
-        if let mail = mail {
-            event = extract(from: mail, event: event)
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(sendViewClose mail: EphemeralMail?) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.sendViewClose.rawValue
-        if let mail = mail {
-            event = extract(from: mail, event: event)
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(createDraft to: [Mail_Address?], cc: [Mail_Address?], bcc: [Mail_Address?], subject: String, bodyLength: Int, isEncrypted: Bool, isSigned: Bool, myKeyID: String) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.createDraft.rawValue
-
-
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(sent from: Mail_Address, to: [Mail_Address], cc: [Mail_Address], bcc: [Mail_Address], subject: String, bodyLength: Int, isEncrypted: Bool, decryptedBodyLength: Int, decryptedWithOldPrivateKey: Bool = false, isSigned: Bool, isCorrectlySigned: Bool = true, signingKeyID: String, myKeyID: String, secureAddresses: [Mail_Address] = [], encryptedForKeyIDs: [String] = [], inviteMailContent: String?, invitationMail: Bool) {
-
+        
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-
-        event["type"] = LoggingEventType.mailSent.rawValue
-        event["from"] = Logger.resolve(mailAddress: from)
-        event["to"] = Logger.resolve(mailAddresses: to)
-        event["cc"] = Logger.resolve(mailAddresses: cc)
-        event["bcc"] = Logger.resolve(mailAddresses: bcc)
-        event["communicationState"] = Logger.communicationState(subject: subject)
-        event["specialMail"] = Logger.specialMail(subject: subject)
-        event["bodyLength"] = bodyLength
-        event["isEncrypted"] = isEncrypted
-        event["decryptedBodyLength"] = decryptedBodyLength
-        event["decryptedWithOldPrivateKey"] = decryptedWithOldPrivateKey
-        event["isSigned"] = isSigned
-        event["isCorrectlySigned"] = isCorrectlySigned
-        event["signingKeyID"] = Logger.resolve(keyID: signingKeyID)
-        event["myKeyID"] = Logger.resolve(keyID: myKeyID)
-        event["secureAddresses"] = Logger.resolve(mailAddresses: secureAddresses) //means the addresses, which received a secure mail
-        event["encryptedForKeyIDs"] = Logger.resolve(keyIDs: encryptedForKeyIDs)
-        if let content = inviteMailContent {
-            event["inviteMailContent"] = content
+        var encState = EncryptionState.NoEncryption
+        if isEncrypted {
+            encState = EncryptionState.ValidedEncryptedWithCurrentKey
         }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        if invitationMail {
-            sendLog()
-        }
-        else {
-            sendCheck()
+        var sigState = SignatureState.NoSignature
+        if isSigned {
+            sigState = SignatureState.ValidSignature
         }
-
-
+        LogData.addMail(enc: encState , sig: sigState, received: false)
+        sendCheck()
     }
-
+    
     static func log(readViewOpen mail: PersistentMail, message: String, draft: Bool = false) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-
-        event["type"] = LoggingEventType.readViewOpen.rawValue
-        event = extract(from: mail, event: event)
-        event["messagePresented"] = message
-        event["draft"] = draft
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(readViewClose message: String, draft: Bool = false) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-
-        event["type"] = LoggingEventType.readViewClose.rawValue
-        event["messagePresented"] = message
-        event["draft"] = draft
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(received mail: PersistentMail) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-
-        event["type"] = LoggingEventType.mailReceived.rawValue
-        event = extract(from: mail, event: event)
-
-        saveToDisk(json: dictToJSON(fields: event))
+        LogData.addMail(mail: mail, received: true)
         sendCheck()
     }
-
+    
     static func log(bitcoinMail gotIt: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-
-        event["type"] = LoggingEventType.gotBitcoinMail.rawValue
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
-
+    
+    
     static func log(delete mail: PersistentMail, toTrash: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        if toTrash {
-            event["type"] = LoggingEventType.mailDeletedToTrash.rawValue
-        } else {
-            event["type"] = LoggingEventType.mailDeletedPersistent.rawValue
-        }
-        // event = extract(from: mail, event: event)
-        event["operation"] = "DeleteMail"
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(archive mail: PersistentMail) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.mailArchived.rawValue
-        event = extract(from: mail, event: event)
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(open indicatorButton: String, mail: PersistentMail?) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.indicatorButtonOpen.rawValue
-        event["indicatorButton"] = indicatorButton
-        if let mail = mail {
-            event["view"] = "readView"
-            event = extract(from: mail, event: event)
-        } else {
-            event["view"] = "sendView"
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
-    static func log(close indicatorButton: String, mail: PersistentMail?, action: String) {
+    
+    static func log(close indicatorButton: LogData.IndicatorButton, mail: PersistentMail?, action: LogData.UserInteractionPopUp, duration: Double) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.indicatorButtonClose.rawValue
-        event["indicatorButton"] = indicatorButton
-        if let mail = mail {
-            event["view"] = "readView"
-            event = extract(from: mail, event: event)
-        } else {
-            event["view"] = "sendView"
-        }
-        event["action"] = action
-
-        saveToDisk(json: dictToJSON(fields: event))
+        LogData.clickOnIndicator(type: indicatorButton, userReaction: action, duration: duration)
         sendCheck()
     }
-
+    
     static func log(showBroken mail: PersistentMail?) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.showBrokenMail.rawValue
-        event["view"] = "readView"
-        if let mail = mail {
-            event = extract(from: mail, event: event)
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
-
+    
     static func log(reactTo mail: PersistentMail?) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.reactButtonTapped.rawValue
-        if let mail = mail {
-            event = extract(from: mail, event: event)
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
+        
     }
-
-    static func log(discover publicKeyID: String, mailAddress: Mail_Address, importChannel: String, knownPrivateKey: Bool, knownBefore: Bool) { //add reference to mail here?
+    
+    static func log(discover publicKeyID: String, mailAddress: Mail_Address, importChannel: LogData.TransferType, knownPrivateKey: Bool, knownBefore: Bool) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        if !knownBefore {
-            event["type"] = LoggingEventType.pubKeyDiscoveryNewKey.rawValue
-        } else {
-            event["type"] = LoggingEventType.pubKeyDiscoveryKnownKey.rawValue
-        }
-        event["keyID"] = Logger.resolve(keyID: publicKeyID)
-        event["mailAddress"] = Logger.resolve(mail_address: mailAddress)
-        event["knownPrivateKey"] = knownPrivateKey //Do we have a private key for it?
-        event["importChannel"] = importChannel
-
-        saveToDisk(json: dictToJSON(fields: event))
+        LogData.importKey(keyType: .publicKey, transferType: importChannel, known: knownBefore)
         sendCheck()
     }
-
+    
     static func log(backgroundFetch newMails: UInt32, duration: Double) {
         if !logging {
             return
         }
-        
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.backgroundFetch.rawValue
-        event["newMails"] = Int(newMails)
-        event["duration"] = duration
-        
-        saveToDisk(json: dictToJSON(fields: event))
     }
     
     static func log(verify keyID: String, open: Bool, success: Bool? = nil) {
         if !logging {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.pubKeyVerification.rawValue
-        event["keyID"] = Logger.resolve(keyID: keyID)
-        var stateString = "open"
-        if !open {
-            stateString = "close"
-        }
-        event["state"] = stateString
-        if let success = success {
-            event["success"] = success
-        }
-
-        saveToDisk(json: dictToJSON(fields: event))
+        LogData.newVerification(successful: success)
         sendCheck()
     }
-
-    /**
-     - parameters:
-        - nrOfTrays: Number of search results
-        - category: 0 is sender, 1 is subject, 2 is message, 3 is everything
-        - opened:   "mail" User opened a message,
-                    "mailList" User opened the mail list,
-                    "contact" User opened contact view,
-                    "searchedInMailList" User searched in the ListView.
-        - keyRecordMailList: Array of MailAddresses that identify the KeyRecord in which the user searched. Nil when not in MailListView.
-     */
+    
     static func log(search nrOfTrays: Int, category: Int, opened: String, keyRecordMailList: [MailAddress]? = nil) {
         guard logging else {
             return
         }
-
-        var event = plainLogDict()
-        event["type"] = LoggingEventType.search.rawValue
-        event["category"] = category
-        event["nrOfTrays"] = nrOfTrays
-        event["opened"] = opened
-        event["keyRecordMailList"] = resolve(mailAddresses: keyRecordMailList ?? [])
-
-        saveToDisk(json: dictToJSON(fields: event))
-        sendCheck()
     }
 
-    static fileprivate func extract(from mail: PersistentMail, event: [String: Any]) -> [String: Any] {
-        var event = event
-        event["from"] = Logger.resolve(mailAddress: mail.from)
-        event["to"] = Logger.resolve(mailAddresses: mail.to)
-        event["cc"] = Logger.resolve(mailAddresses: mail.cc ?? NSSet())
-        event["bcc"] = Logger.resolve(mailAddresses: mail.bcc ?? NSSet())
-        event["communicationState"] = Logger.communicationState(subject: mail.subject ?? "")
-        event["specialMail"] = Logger.specialMail(subject: mail.subject ?? "")
-        event["timeInHeader"] = mail.date.description
-        event["bodyLength"] = (mail.body)?.count
-        event["isEncrypted"] = mail.isEncrypted
-        event["decryptedBodyLength"] = (mail.decryptedBody ?? "").count
-        event["decryptedWithOldPrivateKey"] = mail.decryptedWithOldPrivateKey
-        event["isSigned"] = mail.isSigned
-        event["isCorrectlySigned"] = mail.isCorrectlySigned
-        event["x-Mailer"] = mail.xMailer
-        //TODO:
-        //event["signingKeyID"] = Logger.resolve(keyID: signingKeyID)
-        //event["myKeyID"] = Logger.resolve(keyID: myKeyID)
-
-
-
-        //event["secureAddresses"] = secureAddresses //could mean the addresses, in this mail we have a key for
-        //event["encryptedForKeyIDs"] = Logger.resolve(keyIDs: encryptedForKeyIDs)
-
-        event["trouble"] = mail.trouble
-        event["folder"] = Logger.resolve(folder: mail.folder)
-
-        return event
+    static private func sendLog(logMailAddress: String = logReceiver) {
+        let jsonEncoder = JSONEncoder()
+        if let data = try? jsonEncoder.encode(Maildata()), let text = String(data: data, encoding: .utf8), text.count > 0 {
+            AppDelegate.getAppDelegate().mailHandler.send([logMailAddress], ccEntrys: [], bccEntrys: [], subject: "[Enzevalos] Log", message: text, callback: sendCallback, loggingMail: true)
+        }
+        LogInUserDefaults.handler.reset()
     }
+    
+    static func sendCallback(error: Error?) {
+        guard error == nil else {
+            return
+        }
+        
+        let tmpNextDeadline = Date(timeIntervalSinceNow: TimeInterval(loggingInterval))
+        nextDeadline = tmpNextDeadline
+        UserManager.storeUserValue(nextDeadline as AnyObject?, attribute: Attribute.nextDeadline)
+    }
+    static func log(warning: LogData.WarningType) {
+        LogData.warning(type: warning)
+    }
+    
+    static func log(reactWarning: LogData.WarningType, reaction: LogData.UserWarningReaction) {
+        LogData.warning(type: reactWarning, reaction: reaction)
+    }
+}
 
-    static fileprivate func extract(from mail: EphemeralMail, event: [String: Any]) -> [String: Any] {
-        var event = event
-        event["to"] = Logger.resolve(mailAddresses: mail.to)
-        event["cc"] = Logger.resolve(mailAddresses: mail.cc ?? NSSet())
-        event["bcc"] = Logger.resolve(mailAddresses: mail.bcc ?? NSSet())
-        event["communicationState"] = Logger.communicationState(subject: mail.subject ?? "")
-        event["specialMail"] = Logger.specialMail(subject: mail.subject ?? "")
-        event["bodyLength"] = (mail.body)?.count
-        //TODO:
-        //event["signingKeyID"] = Logger.resolve(keyID: signingKeyID)
-        //event["myKeyID"] = Logger.resolve(keyID: myKeyID)
-
-
-
-        //event["secureAddresses"] = secureAddresses //could mean the addresses, in this mail we have a key for
-        //event["encryptedForKeyIDs"] = Logger.resolve(keyIDs: encryptedForKeyIDs)
+/*
+    Logged data according privacy policy (see: https://letterbox-app.org/privacy.html)
+ */
 
-        return event
+public class LogInUserDefaults {
+    static let handler = LogInUserDefaults()
+    
+    private let domain = "letterbox.logging"
+    private let logger: UserDefaults
+    private let startDateName = "startDate"
+    private let prefix = "letterbox"
+    
+    init() {
+        if let newDefault =  UserDefaults.init(suiteName: domain) {
+            logger = newDefault
+        }
+        else {
+            logger = UserDefaults.standard
+        }
+        if logger.data(forKey: startDateName) == nil {
+            logger.set(Date(), forKey: "\(prefix).\(startDateName)")
+        }
     }
-
-    static func communicationState(subject: String) -> String {
-        if subject == "" {
-            return ""
+    
+    func incrementEventCounter(eventName: String) {
+        let oldValue = logger.integer(forKey: "\(prefix).\(eventName)")
+        let counter =  oldValue + 1
+        logger.set(counter, forKey: "\(prefix).\(eventName)")
+        
+    }
+    
+    func reset() {
+        for (key, value) in logger.dictionaryRepresentation() {
+            if let _ = value as? Int {
+                logger.set(0, forKey: key)
+            }
         }
-        var oldSubject = subject
-        var newSubject = ""
-        var hasPrefix = true
-
-        while hasPrefix {
-            if oldSubject.hasPrefix("Re: ") || oldSubject.hasPrefix("RE: ") || oldSubject.hasPrefix("re: ") || oldSubject.hasPrefix("AW: ") || oldSubject.hasPrefix("Aw: ") || oldSubject.hasPrefix("aw: ") {
-                newSubject += "Re: "
-                oldSubject = String(oldSubject[oldSubject.index(oldSubject.startIndex, offsetBy: 4)...]) //damn swift3!
-            } else if oldSubject.hasPrefix("Fwd: ") || oldSubject.hasPrefix("FWD: ") || oldSubject.hasPrefix("fwd: ") {
-                newSubject += "Fwd: "
-                oldSubject = String(oldSubject[oldSubject.index(oldSubject.startIndex, offsetBy: 5)...])
-            } else if oldSubject.hasPrefix("WG: ") || oldSubject.hasPrefix("Wg: ") || oldSubject.hasPrefix("wg: ") {
-                newSubject += "Fwd: "
-                oldSubject = String(oldSubject[oldSubject.index(oldSubject.startIndex, offsetBy: 4)...])
-            } else {
-                hasPrefix = false
+        logger.set(Date(), forKey: "\(prefix).\(startDateName)")
+    }
+    
+    func calculateDuration(eventName: String, duration: Double) {
+        // Use online algo: See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
+        let nameMean = "|mean"
+        let nameSqD = "|sqD" // squared distance from the mean
+        // load values
+        let n = logger.integer(forKey: "\(prefix).\(eventName)") // we assume that event was logged before!
+        var mean = logger.double(forKey: "\(prefix).\(eventName+nameMean)")
+        var sqD = logger.double(forKey: "\(prefix).\(eventName+nameSqD)")
+        
+        // See:
+        //      Welford, B. P. (1962). "Note on a method for calculating corrected sums of squares and products". or
+        //      Donald E. Knuth (1998). The Art of Computer Programming, volume 2: Seminumerical Algorithms, 3rd edn., p. 232
+        let delta = duration - mean
+        mean = mean + (delta / Double(n))
+        let delta2 = duration - mean
+        sqD = sqD + delta * delta2
+        
+        // update values
+        logger.set(sqD, forKey: "\(prefix).\(eventName+nameSqD)")
+        logger.set(mean, forKey: "\(prefix).\(eventName+nameMean)")
+    }
+    
+    var loggedEvents: [String: Int] {
+        get {
+            var events = [String: Int]()
+            for (key, value) in logger.dictionaryRepresentation() {
+                if key.starts(with: prefix), let v = value as? Int {
+                    events[key] = v
+                }
             }
+            return events
         }
-
-        return newSubject
     }
-
-    static func specialMail(subject: String) -> String {
-        if subject.contains(NSLocalizedString("inviteSubject", comment: "subject of invitation email")) {
-            return "invitation"
+    
+    var loggedDuration: [String: Double] {
+        var events = [String: Double]()
+        for (key, value) in logger.dictionaryRepresentation() {
+            if key.starts(with: prefix), let v = value as? Double {
+                events[key] = v
+            }
         }
-        return ""
+        return events
     }
+}
 
-    //takes backendFolderPath
-    static func resolve(folder: Folder) -> String {
-        let folderPath = folder.path
-        if folderPath == UserManager.backendSentFolderPath {
-            return "sent"
-        }
-        if folderPath == UserManager.backendDraftFolderPath {
-            return "draft"
+public class LogData {
+    
+    static func newSimpleEvent(event: SimpleEvents) {
+        LogInUserDefaults.handler.incrementEventCounter(eventName: event.name)
+    }
+    static func addMail(mail: PersistentMail, received: Bool) {
+        let enc = mail.encState
+        let sig = mail.sigState
+        addMail(enc: enc, sig: sig, received: received)
+    }
+    
+    static func addMail(enc: EncryptionState, sig: SignatureState, received: Bool) {
+        let key = LogData.makeMailKey(enc: enc, sig: sig, received: received)
+        LogInUserDefaults.handler.incrementEventCounter(eventName: key)
+    }
+    
+    private static func makeMailKey(enc: EncryptionState, sig: SignatureState, received: Bool) -> String {
+        var key = "\(enc.name)&\(sig.name)"
+        if received {
+            key = "in|" + key
         }
-        if folderPath == UserManager.backendInboxFolderPath {
-            return "inbox"
+        else {
+            key = "out|"+key
         }
-        if folderPath == UserManager.backendTrashFolderPath {
-            return "trash"
+        return key
+    }
+    
+    static func newVerification(successful: Bool?) {
+        var event = "verification"
+        if let successful = successful {
+            if successful {
+                event = "successful|"+event
+            }
+            else {
+                event = "failed|"+event
+            }
         }
-        if folderPath == UserManager.backendArchiveFolderPath {
-            return "archive"
+        else {
+            event = "unknown|"+event
         }
-        return folder.pseudonym
+       
+        LogInUserDefaults.handler.incrementEventCounter(eventName: event)
     }
-
-    //get an pseudonym for a mailAddress
-    static func resolve(mailAddress: MailAddress) -> String {
-        if let addr = mailAddress as? Mail_Address {
-            return resolve(mail_address: addr)
-        } else if mailAddress is CNMailAddressExtension {
-            return "CNMailAddress"
+    
+    static func importKey(keyType: KeyType, transferType: TransferType, known: Bool) {
+        var new = "strange"
+        if known {
+            new = "known"
         }
-        return "unknownMailAddressType"
+        LogInUserDefaults.handler.incrementEventCounter(eventName: "importKey|\(keyType.name)&\(transferType.name)&\(new)")
     }
-
-    static func resolve(mail_address: Mail_Address) -> String {
-        if mail_address.isUser {
-            return "self"
-        }
-        return mail_address.pseudonym
+    
+    static func exportKey(keyType: KeyType, transferType: TransferType) {
+        LogInUserDefaults.handler.incrementEventCounter(eventName: "exportKey|\(keyType.name)&\(transferType.name)")
     }
 
-    static func resolve(mailAddresses: NSSet) -> [String] {
-        var result: [String] = []
-        for addr in mailAddresses {
-            if let addr = addr as? Mail_Address {
-                result.append(resolve(mail_address: addr))
-            } else if addr is CNMailAddressExtension {
-                result.append("CNMailAddress")
-            } else {
-                result.append("unknownMailAddressType")
+    
+    static func warning(type: WarningType, reaction: UserWarningReaction) {
+        let name = "Warning|\(type.name)&\(reaction.name)"
+        LogInUserDefaults.handler.incrementEventCounter(eventName: name)
+    }
+    
+    static func warning(type: WarningType) {
+        let name = "Warning|\(type.name)"
+        LogInUserDefaults.handler.incrementEventCounter(eventName: name)
+    }
+    
+    static func clickOnIndicator(type: IndicatorButton, userReaction: UserInteractionPopUp, duration: Double) {
+        let name = "clickIndicator:\(type.name)&\(userReaction)"
+        LogInUserDefaults.handler.incrementEventCounter(eventName: name)
+        LogInUserDefaults.handler.calculateDuration(eventName: name, duration: duration)
+    }
+    
+    static func viewOnboardingSlide(type: IntroState, duration: Double) {
+        LogInUserDefaults.handler.incrementEventCounter(eventName: type.name)
+        LogInUserDefaults.handler.calculateDuration(eventName: type.name, duration: duration)
+    }
+    
+    enum SimpleEvents {
+        case newSession, keyDetailsView, invationMail, loginAttempt
+        
+        var name: String {
+            get {
+                switch self {
+                case .newSession:
+                    return "newSession"
+                case .keyDetailsView:
+                    return "keyDetailsView"
+                case .invationMail:
+                    return "inviation"
+                case .loginAttempt:
+                    return "loginAttempt"
+                }
             }
         }
-        return result
     }
-
-    static func resolve(mailAddresses: [Mail_Address]) -> [String] {
-        var result: [String] = []
-        for addr in mailAddresses {
-            result.append(resolve(mail_address: addr))
+    
+    enum KeyType {
+        case publicKey, secretKey
+        
+        var name: String {
+            switch self {
+            case .publicKey:
+                return "PublicKey"
+            case .secretKey:
+                return "SecretKey"
+            }
         }
-        return result
     }
-
-    static func resolve(mailAddresses: [MailAddress]) -> [String] {
-        var result: [String] = []
-        for addr in mailAddresses {
-            if let addr = addr as? Mail_Address {
-                result.append(resolve(mail_address: addr))
-            } else if addr is CNMailAddressExtension {
-                result.append("CNMailAddress")
-            } else {
-                result.append("unknownMailAddressType")
+    
+    enum TransferType {
+        case autocrypt, mail, iTunes, qr, generated
+        
+        var name: String {
+            switch self {
+            case .autocrypt:
+                return "autocrypt"
+            case .mail:
+                return "mail"
+            case .iTunes:
+                return "iTunes"
+            case .qr:
+                return "QR-Code"
+            case .generated:
+                return "generated"
             }
         }
-        return result
     }
-
-    //get an pseudonym for a keyID
-    static func resolve(keyID: String) -> String {
-        if let key = DataHandler.handler.findKey(keyID: keyID) {
-            return key.pseudonym
+    
+    enum WarningType {
+        case newKey, notConfidential, error, none, unableToDecrypt, unableToDecryptTravel, deletedWhileTravel
+        var name: String {
+            get {
+                switch self {
+                case .newKey:
+                    return "newKey"
+                case .notConfidential:
+                    return "notConfidential"
+                case .error:
+                    return "error"
+                case .none:
+                    return "none"
+                case .unableToDecrypt:
+                    return "unableToDecrypt"
+                case .unableToDecryptTravel:
+                    return "unableToDecryptTravel"
+                case .deletedWhileTravel:
+                    return "deletedWhileTravel"
+                }
+            }
         }
-        return "noKeyID"
-    }
-
-    static func resolve(key: PersistentKey) -> String {
-        return key.pseudonym
     }
-
-    static func resolve(keyIDs: [String]) -> [String] {
-        var result: [String] = []
-        for id in keyIDs {
-            result.append(resolve(keyID: id))
+    
+    enum UserWarningReaction {
+        case ignore, requestConfirmation, clickButton
+        
+        var name: String {
+            get {
+                switch self {
+                case .ignore:
+                    return "ignore"
+                case .requestConfirmation:
+                    return "requestConfirmation"
+                case .clickButton:
+                    return "clickButton"
+                }
+            }
         }
-        return result
     }
-
-    static func saveToDisk(json: String, fileName: String = defaultFileName) {
-
-        if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
-
-            let fileURL = dir.appendingPathComponent(fileName)
-
-            if FileManager.default.fileExists(atPath: fileURL.path) {
-                // append
-                do {
-                    let fileHandle = try FileHandle(forUpdating: fileURL)
-
-                    fileHandle.seekToEndOfFile()
-                    if let encoded = "\n\(json),".data(using: .utf8) {
-                        fileHandle.write(encoded)
-                    }
-                    fileHandle.closeFile()
-                }
-                catch {
-                    print("Error while appending to logfile: \(error.localizedDescription)")
-                }
-            } else {
-                // write new
-                do {
-                    try json.write(to: fileURL, atomically: false, encoding: .utf8)
-                }
-                catch {
-                    print("Error while writing logfile: \(error.localizedDescription)")
+    
+    enum IndicatorButton {
+        case confidential, signedOnly, encryptedOnly, notConfidential, unableToDecrypt, error
+        
+        var name: String {
+            get {
+                switch self {
+                case .confidential:
+                    return "confidential"
+                case .signedOnly:
+                    return "signedOnly"
+                case . encryptedOnly:
+                    return "encryptedOnly"
+                case .notConfidential:
+                    return "NotConfidential"
+                case .unableToDecrypt:
+                    return "unableToDecrypt"
+                case .error:
+                    return "error"
                 }
             }
-
         }
     }
-
-    static func sendLog(fileName: String = defaultFileName, logMailAddress: String = logReceiver) {
-
-        if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
-
-            let fileURL = dir.appendingPathComponent(fileName)
-
-            // reading
-            do {
-                let currentContent = try String(contentsOf: fileURL, encoding: .utf8)
-                if !currentContent.isEmpty {
-                    AppDelegate.getAppDelegate().mailHandler.send([logMailAddress], ccEntrys: [], bccEntrys: [], subject: "[Enzevalos] Log", message: "{\"studyID\":\"" + studyID + "\",\"data\":" + "[" + currentContent.dropLast() + "\n]" + "}", callback: sendCallback, loggingMail: true)
+    
+    enum UserInteractionPopUp {
+        case close, inviteOther, disableConf, enableConf, exportKey, moreInfo, travelFollowUp, EnableEnforceConf, DisableEnforceConf
+        
+        var name: String {
+            get {
+                switch self {
+                case .close:
+                    return "close"
+                case .disableConf:
+                    return "disableConf"
+                case .enableConf:
+                    return "enableConfAgain"
+                case .inviteOther:
+                    return "invite"
+                case .exportKey:
+                    return "exportKey"
+                case .moreInfo:
+                    return "moreInformation"
+                case .travelFollowUp:
+                    return "travelFollowUp"
+                case .EnableEnforceConf:
+                    return "enforceConf"
+                case .DisableEnforceConf:
+                    return "turnEnforceConfOff"
+                    
                 }
             }
-            catch {
-                print("Error while reading logfile: \(error.localizedDescription)")
-            }
         }
     }
+}
 
-    static func sendCallback(error: Error?) {
-        guard error == nil else {
-            print(error!)
-            return
+/*
+ Outgoing data:
+ reads stored values and
+ calculates other data
+ send data
+ */
+public class Maildata: Encodable {
+    let studyID = StudySettings.studyID
+    var studySetting: String {
+        get {
+            let symbol = StudySettings.securityIndicator.rawValue
+            return "studyparameter|\(symbol)"
         }
-
-        clearLog()
-        let tmpNextDeadline = Date(timeIntervalSinceNow: TimeInterval(loggingInterval))
-        nextDeadline = tmpNextDeadline
-        UserManager.storeUserValue(nextDeadline as AnyObject?, attribute: Attribute.nextDeadline)
     }
+    var AddresseswithoutKeys: Int = 0
+    var addressesWithKeys: [Int: Int] = [:]
+    let storedDurations = LogInUserDefaults.handler.loggedDuration
 
-    static func clearLog(fileName: String = defaultFileName) {
-        if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
-
-            let fileURL = dir.appendingPathComponent(fileName)
-
-            do {
-                try String().write(to: fileURL, atomically: false, encoding: .utf8)
-            }
-            catch {
-                print("Error while clearing logfile: \(error.localizedDescription)")
-            }
-        }
+    
+    
+    init() {
+        self.collectPublicKeyInfos()
+    }
+    
+    
+    private func collectPublicKeyInfos() {
+        let handler = DataHandler.handler
+        let numOfNoKeyAddr = handler.findMailAddress(withKey: false).count
+        let numOfKeyAddr = handler.findMailAddress(withKey: true)
+        var numOfKeysPerAddr = [Int: Int] ()
+        for addr in numOfKeyAddr {
+            let counterKeys = addr.publicKeys.count
+            let before = numOfKeysPerAddr[counterKeys] ?? 0
+            numOfKeysPerAddr[counterKeys] = before + 1
+        }
+        AddresseswithoutKeys = numOfNoKeyAddr
+        addressesWithKeys = numOfKeysPerAddr
     }
 }
diff --git a/enzevalos_iphone/LoggerDetail.swift b/enzevalos_iphone/LoggerDetail.swift
new file mode 100644
index 0000000000000000000000000000000000000000..82d396827bb34dd5dcd1697c069ce36fe94c1f67
--- /dev/null
+++ b/enzevalos_iphone/LoggerDetail.swift
@@ -0,0 +1,948 @@
+//
+//  Logger.swift
+//  enzevalos_iphone
+//
+//  Created by jakobsbode on 25.10.17.
+//  Copyright © 2018 fu-berlin.
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+//
+
+import Foundation
+
+class LoggerDetail {
+
+    static var logging = StudySettings.studyMode
+
+    static let queue = DispatchQueue(label: "logging", qos: .background)
+
+    static let defaultFileName = "log.json"
+    static let loggingInterval = 21600 //60*60*6 seconds = 6 hours
+    static let resendInterval = 5 * 60
+    static let logReceiver = LOGGING_MAIL_ADR
+
+    static var nextDeadline = (UserManager.loadUserValue(Attribute.nextDeadline) as? Date) ?? Date()
+
+    static var studyID = StudySettings.studyID //identifies the participant in the study
+
+    
+    
+    static fileprivate func sendCheck() {
+        if nextDeadline <= Date() && AppDelegate.getAppDelegate().currentReachabilityStatus != .notReachable && UserManager.loadUserValue(Attribute.accountname) != nil && UserDefaults.standard.bool(forKey: "launchedBefore"){
+            //Do not send duplicate mails
+            let tmpNextDeadline = Date(timeIntervalSinceNow: TimeInterval(resendInterval))
+            nextDeadline = tmpNextDeadline
+            UserManager.storeUserValue(nextDeadline as AnyObject?, attribute: Attribute.nextDeadline)
+            sendLog()
+        }
+    }
+
+    static fileprivate func plainLogDict() -> [String: Any] {
+        var fields: [String: Any] = [:]
+        let now = Date()
+        fields["timestamp"] = now.description
+        fields["lang"] = Locale.current.languageCode
+        return fields
+    }
+
+    static fileprivate func dictToJSON(fields: [String: Any]) -> String {
+        do {
+            let jsonData = try JSONSerialization.data(withJSONObject: fields)
+            if let json = String(data: jsonData, encoding: String.Encoding.utf8) {
+                return json
+            }
+            return ""
+        } catch {
+            return "{\"error\":\"json conversion failed\"}"
+        }
+    }
+
+    static func log(setupStudy studypara: [StudyParameterProtocol.Type], alreadyRegistered: Bool) {
+        if !logging {
+            return
+        }
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.setupStudy.rawValue
+        
+        //event["language"] =
+       
+        for para in studypara{
+            event[para.name] = para.load().value
+        }
+        event["alreadyRegistered"] = alreadyRegistered
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(startApp onboarding: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.appStart.rawValue
+        event["onboarding"] = onboarding
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(terminateApp: Void) {
+        if !logging {
+            return
+        }
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.appTerminate.rawValue
+        saveToDisk(json: dictToJSON(fields: event))
+    }
+
+    static func log(background goto: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.appBackground.rawValue
+        event["going to"] = goto //true -> goto background; false -> comming from background
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(onboardingState onboardingSection: String) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.onboardingState.rawValue
+        event["onboardingSection"] = onboardingSection
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(onboardingPageTransition from: Int, to: Int, onboardingSection: String) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.onboardingPageTransition.rawValue
+        event["from"] = from
+        event["to"] = to
+        event["onboardingSection"] = onboardingSection
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(contactViewOpen keyRecord: KeyRecord?, otherRecords: [KeyRecord]?, isUser: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.contactViewOpen.rawValue
+
+        if let keyRecord = keyRecord {
+            if let keyID = keyRecord.keyID {
+                event["keyID"] = resolve(keyID: keyID)
+            } else {
+                event["keyID"] = "nil"
+            }
+            event["mailaddresses"] = resolve(mailAddresses: keyRecord.addresses)
+        }
+        event["isUser"] = isUser
+        if isUser {
+            let (contact, mail) = GamificationData.sharedInstance.getSecureProgress()
+            event["gamificationContact"] = contact
+            event["gamificationMail"] = mail
+        }
+        event["numberOfOtherRecords"] = (otherRecords ?? []).count
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(badgeCaseViewOpen badges: [Badges]) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.badgeCaseViewOpen.rawValue
+
+        var achievedBadges: [String] = []
+        var missingBadges: [String] = []
+
+        for badge in badges {
+            if badge.isAchieved() {
+                achievedBadges.append(badge.displayName)
+            } else {
+                missingBadges.append(badge.displayName)
+            }
+        }
+
+        event["achievedBadges"] = achievedBadges
+        event["missingBadges"] = missingBadges
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(badgeCaseViewClose badges: [Badges]) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.badgeCaseViewClose.rawValue
+
+        var achievedBadges: [String] = []
+        var missingBadges: [String] = []
+
+        for badge in badges {
+            if badge.isAchieved() {
+                achievedBadges.append(badge.displayName)
+            } else {
+                missingBadges.append(badge.displayName)
+            }
+        }
+
+        event["achievedBadges"] = achievedBadges
+        event["missingBadges"] = missingBadges
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(contactViewClose keyRecord: KeyRecord?, otherRecords: [KeyRecord]?, isUser: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.contactViewClose.rawValue
+
+        if let keyRecord = keyRecord {
+            if let keyID = keyRecord.keyID {
+                event["keyID"] = resolve(keyID: keyID)
+            } else {
+                event["keyID"] = "nil"
+            }
+            event["mailaddresses"] = resolve(mailAddresses: keyRecord.addresses)
+        }
+        event["isUser"] = isUser
+        if isUser {
+            let (contact, mail) = GamificationData.sharedInstance.getSecureProgress()
+            event["gamificationContact"] = contact
+            event["gamificationMail"] = mail
+        }
+        event["numberOfOtherRecords"] = (otherRecords ?? []).count
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(keyViewOpen keyID: String) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.keyViewOpen.rawValue
+        event["keyID"] = resolve(keyID: keyID)
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(keyViewClose keyID: String, secondsOpened: Int) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.keyViewClose.rawValue
+        event["keyID"] = resolve(keyID: keyID)
+        event["opened for seconds"] = secondsOpened
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(exportKeyViewOpen view: Int) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.exportKeyViewOpen.rawValue
+        event["view"] = view
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(exportKeyViewClose view: Int) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.exportKeyViewClose.rawValue
+        event["view"] = view
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(exportKeyViewButton send: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.exportKeyViewClose.rawValue
+        if send {
+            event["case"] = "sendMail"
+        } else {
+            event["case"] = "deletePasscode"
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(importPrivateKeyPopupOpen mail: PersistentMail?) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.importPrivateKeyPopupOpen.rawValue
+        if let mail = mail {
+            event = extract(from: mail, event: event)
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(importPrivateKeyPopupClose mail: PersistentMail?, doImport: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.importPrivateKeyPopupClose.rawValue
+        event["doImport"] = doImport
+        if let mail = mail {
+            event = extract(from: mail, event: event)
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(importPrivateKey mail: PersistentMail?, success: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.importPrivateKey.rawValue
+        event["success"] = success
+        if let mail = mail {
+            event = extract(from: mail, event: event)
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(sendViewOpen mail: EphemeralMail?) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.sendViewOpen.rawValue
+        if let mail = mail {
+            event = extract(from: mail, event: event)
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(sendViewClose mail: EphemeralMail?) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.sendViewClose.rawValue
+        if let mail = mail {
+            event = extract(from: mail, event: event)
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(createDraft to: [Mail_Address?], cc: [Mail_Address?], bcc: [Mail_Address?], subject: String, bodyLength: Int, isEncrypted: Bool, isSigned: Bool, myKeyID: String) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.createDraft.rawValue
+
+
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(sent from: Mail_Address, to: [Mail_Address], cc: [Mail_Address], bcc: [Mail_Address], subject: String, bodyLength: Int, isEncrypted: Bool, decryptedBodyLength: Int, decryptedWithOldPrivateKey: Bool = false, isSigned: Bool, isCorrectlySigned: Bool = true, signingKeyID: String, myKeyID: String, secureAddresses: [Mail_Address] = [], encryptedForKeyIDs: [String] = [], inviteMailContent: String?, invitationMail: Bool) {
+
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+
+        event["type"] = LoggingEventType.mailSent.rawValue
+        event["from"] = LoggerDetail.resolve(mailAddress: from)
+        event["to"] = LoggerDetail.resolve(mailAddresses: to)
+        event["cc"] = LoggerDetail.resolve(mailAddresses: cc)
+        event["bcc"] = LoggerDetail.resolve(mailAddresses: bcc)
+        event["communicationState"] = LoggerDetail.communicationState(subject: subject)
+        event["specialMail"] = LoggerDetail.specialMail(subject: subject)
+        event["bodyLength"] = bodyLength
+        event["isEncrypted"] = isEncrypted
+        event["decryptedBodyLength"] = decryptedBodyLength
+        event["decryptedWithOldPrivateKey"] = decryptedWithOldPrivateKey
+        event["isSigned"] = isSigned
+        event["isCorrectlySigned"] = isCorrectlySigned
+        event["signingKeyID"] = LoggerDetail.resolve(keyID: signingKeyID)
+        event["myKeyID"] = LoggerDetail.resolve(keyID: myKeyID)
+        event["secureAddresses"] = LoggerDetail.resolve(mailAddresses: secureAddresses) //means the addresses, which received a secure mail
+        event["encryptedForKeyIDs"] = LoggerDetail.resolve(keyIDs: encryptedForKeyIDs)
+        if let content = inviteMailContent {
+            event["inviteMailContent"] = content
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        if invitationMail {
+            sendLog()
+        }
+        else {
+            sendCheck()
+        }
+
+
+    }
+
+    static func log(readViewOpen mail: PersistentMail, message: String, draft: Bool = false) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+
+        event["type"] = LoggingEventType.readViewOpen.rawValue
+        event = extract(from: mail, event: event)
+        event["messagePresented"] = message
+        event["draft"] = draft
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(readViewClose message: String, draft: Bool = false) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+
+        event["type"] = LoggingEventType.readViewClose.rawValue
+        event["messagePresented"] = message
+        event["draft"] = draft
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(received mail: PersistentMail) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+
+        event["type"] = LoggingEventType.mailReceived.rawValue
+        event = extract(from: mail, event: event)
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(bitcoinMail gotIt: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+
+        event["type"] = LoggingEventType.gotBitcoinMail.rawValue
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+
+    static func log(delete mail: PersistentMail, toTrash: Bool) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        if toTrash {
+            event["type"] = LoggingEventType.mailDeletedToTrash.rawValue
+        } else {
+            event["type"] = LoggingEventType.mailDeletedPersistent.rawValue
+        }
+        // event = extract(from: mail, event: event)
+        event["operation"] = "DeleteMail"
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(archive mail: PersistentMail) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.mailArchived.rawValue
+        event = extract(from: mail, event: event)
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(open indicatorButton: String, mail: PersistentMail?) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.indicatorButtonOpen.rawValue
+        event["indicatorButton"] = indicatorButton
+        if let mail = mail {
+            event["view"] = "readView"
+            event = extract(from: mail, event: event)
+        } else {
+            event["view"] = "sendView"
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(close indicatorButton: String, mail: PersistentMail?, action: String) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.indicatorButtonClose.rawValue
+        event["indicatorButton"] = indicatorButton
+        if let mail = mail {
+            event["view"] = "readView"
+            event = extract(from: mail, event: event)
+        } else {
+            event["view"] = "sendView"
+        }
+        event["action"] = action
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(showBroken mail: PersistentMail?) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.showBrokenMail.rawValue
+        event["view"] = "readView"
+        if let mail = mail {
+            event = extract(from: mail, event: event)
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(reactTo mail: PersistentMail?) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.reactButtonTapped.rawValue
+        if let mail = mail {
+            event = extract(from: mail, event: event)
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(discover publicKeyID: String, mailAddress: Mail_Address, importChannel: String, knownPrivateKey: Bool, knownBefore: Bool) { //add reference to mail here?
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        if !knownBefore {
+            event["type"] = LoggingEventType.pubKeyDiscoveryNewKey.rawValue
+        } else {
+            event["type"] = LoggingEventType.pubKeyDiscoveryKnownKey.rawValue
+        }
+        event["keyID"] = LoggerDetail.resolve(keyID: publicKeyID)
+        event["mailAddress"] = LoggerDetail.resolve(mail_address: mailAddress)
+        event["knownPrivateKey"] = knownPrivateKey //Do we have a private key for it?
+        event["importChannel"] = importChannel
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static func log(backgroundFetch newMails: UInt32, duration: Double) {
+        if !logging {
+            return
+        }
+        
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.backgroundFetch.rawValue
+        event["newMails"] = Int(newMails)
+        event["duration"] = duration
+        
+        saveToDisk(json: dictToJSON(fields: event))
+    }
+    
+    static func log(verify keyID: String, open: Bool, success: Bool? = nil) {
+        if !logging {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.pubKeyVerification.rawValue
+        event["keyID"] = LoggerDetail.resolve(keyID: keyID)
+        var stateString = "open"
+        if !open {
+            stateString = "close"
+        }
+        event["state"] = stateString
+        if let success = success {
+            event["success"] = success
+        }
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    /**
+     - parameters:
+        - nrOfTrays: Number of search results
+        - category: 0 is sender, 1 is subject, 2 is message, 3 is everything
+        - opened:   "mail" User opened a message,
+                    "mailList" User opened the mail list,
+                    "contact" User opened contact view,
+                    "searchedInMailList" User searched in the ListView.
+        - keyRecordMailList: Array of MailAddresses that identify the KeyRecord in which the user searched. Nil when not in MailListView.
+     */
+    static func log(search nrOfTrays: Int, category: Int, opened: String, keyRecordMailList: [MailAddress]? = nil) {
+        guard logging else {
+            return
+        }
+
+        var event = plainLogDict()
+        event["type"] = LoggingEventType.search.rawValue
+        event["category"] = category
+        event["nrOfTrays"] = nrOfTrays
+        event["opened"] = opened
+        event["keyRecordMailList"] = resolve(mailAddresses: keyRecordMailList ?? [])
+
+        saveToDisk(json: dictToJSON(fields: event))
+        sendCheck()
+    }
+
+    static fileprivate func extract(from mail: PersistentMail, event: [String: Any]) -> [String: Any] {
+        var event = event
+        event["from"] = LoggerDetail.resolve(mailAddress: mail.from)
+        event["to"] = LoggerDetail.resolve(mailAddresses: mail.to)
+        event["cc"] = LoggerDetail.resolve(mailAddresses: mail.cc ?? NSSet())
+        event["bcc"] = LoggerDetail.resolve(mailAddresses: mail.bcc ?? NSSet())
+        event["communicationState"] = LoggerDetail.communicationState(subject: mail.subject ?? "")
+        event["specialMail"] = LoggerDetail.specialMail(subject: mail.subject ?? "")
+        event["timeInHeader"] = mail.date.description
+        event["bodyLength"] = (mail.body)?.count
+        event["isEncrypted"] = mail.isEncrypted
+        event["decryptedBodyLength"] = (mail.decryptedBody ?? "").count
+        event["decryptedWithOldPrivateKey"] = mail.decryptedWithOldPrivateKey
+        event["isSigned"] = mail.isSigned
+        event["isCorrectlySigned"] = mail.isCorrectlySigned
+        event["x-Mailer"] = mail.xMailer
+        //TODO:
+        //event["signingKeyID"] = Logger.resolve(keyID: signingKeyID)
+        //event["myKeyID"] = Logger.resolve(keyID: myKeyID)
+
+
+
+        //event["secureAddresses"] = secureAddresses //could mean the addresses, in this mail we have a key for
+        //event["encryptedForKeyIDs"] = Logger.resolve(keyIDs: encryptedForKeyIDs)
+
+        event["trouble"] = mail.trouble
+        event["folder"] = LoggerDetail.resolve(folder: mail.folder)
+
+        return event
+    }
+
+    static fileprivate func extract(from mail: EphemeralMail, event: [String: Any]) -> [String: Any] {
+        var event = event
+        event["to"] = LoggerDetail.resolve(mailAddresses: mail.to)
+        event["cc"] = LoggerDetail.resolve(mailAddresses: mail.cc ?? NSSet())
+        event["bcc"] = LoggerDetail.resolve(mailAddresses: mail.bcc ?? NSSet())
+        event["communicationState"] = LoggerDetail.communicationState(subject: mail.subject ?? "")
+        event["specialMail"] = LoggerDetail.specialMail(subject: mail.subject ?? "")
+        event["bodyLength"] = (mail.body)?.count
+        //TODO:
+        //event["signingKeyID"] = Logger.resolve(keyID: signingKeyID)
+        //event["myKeyID"] = Logger.resolve(keyID: myKeyID)
+
+
+
+        //event["secureAddresses"] = secureAddresses //could mean the addresses, in this mail we have a key for
+        //event["encryptedForKeyIDs"] = Logger.resolve(keyIDs: encryptedForKeyIDs)
+
+        return event
+    }
+
+    static func communicationState(subject: String) -> String {
+        if subject == "" {
+            return ""
+        }
+        var oldSubject = subject
+        var newSubject = ""
+        var hasPrefix = true
+
+        while hasPrefix {
+            if oldSubject.hasPrefix("Re: ") || oldSubject.hasPrefix("RE: ") || oldSubject.hasPrefix("re: ") || oldSubject.hasPrefix("AW: ") || oldSubject.hasPrefix("Aw: ") || oldSubject.hasPrefix("aw: ") {
+                newSubject += "Re: "
+                oldSubject = String(oldSubject[oldSubject.index(oldSubject.startIndex, offsetBy: 4)...]) //damn swift3!
+            } else if oldSubject.hasPrefix("Fwd: ") || oldSubject.hasPrefix("FWD: ") || oldSubject.hasPrefix("fwd: ") {
+                newSubject += "Fwd: "
+                oldSubject = String(oldSubject[oldSubject.index(oldSubject.startIndex, offsetBy: 5)...])
+            } else if oldSubject.hasPrefix("WG: ") || oldSubject.hasPrefix("Wg: ") || oldSubject.hasPrefix("wg: ") {
+                newSubject += "Fwd: "
+                oldSubject = String(oldSubject[oldSubject.index(oldSubject.startIndex, offsetBy: 4)...])
+            } else {
+                hasPrefix = false
+            }
+        }
+
+        return newSubject
+    }
+
+    static func specialMail(subject: String) -> String {
+        if subject.contains(NSLocalizedString("inviteSubject", comment: "subject of invitation email")) {
+            return "invitation"
+        }
+        return ""
+    }
+
+    //takes backendFolderPath
+    static func resolve(folder: Folder) -> String {
+        let folderPath = folder.path
+        if folderPath == UserManager.backendSentFolderPath {
+            return "sent"
+        }
+        if folderPath == UserManager.backendDraftFolderPath {
+            return "draft"
+        }
+        if folderPath == UserManager.backendInboxFolderPath {
+            return "inbox"
+        }
+        if folderPath == UserManager.backendTrashFolderPath {
+            return "trash"
+        }
+        if folderPath == UserManager.backendArchiveFolderPath {
+            return "archive"
+        }
+        return folder.pseudonym
+    }
+
+    //get an pseudonym for a mailAddress
+    static func resolve(mailAddress: MailAddress) -> String {
+        if let addr = mailAddress as? Mail_Address {
+            return resolve(mail_address: addr)
+        } else if mailAddress is CNMailAddressExtension {
+            return "CNMailAddress"
+        }
+        return "unknownMailAddressType"
+    }
+
+    static func resolve(mail_address: Mail_Address) -> String {
+        if mail_address.isUser {
+            return "self"
+        }
+        return mail_address.pseudonym
+    }
+
+    static func resolve(mailAddresses: NSSet) -> [String] {
+        var result: [String] = []
+        for addr in mailAddresses {
+            if let addr = addr as? Mail_Address {
+                result.append(resolve(mail_address: addr))
+            } else if addr is CNMailAddressExtension {
+                result.append("CNMailAddress")
+            } else {
+                result.append("unknownMailAddressType")
+            }
+        }
+        return result
+    }
+
+    static func resolve(mailAddresses: [Mail_Address]) -> [String] {
+        var result: [String] = []
+        for addr in mailAddresses {
+            result.append(resolve(mail_address: addr))
+        }
+        return result
+    }
+
+    static func resolve(mailAddresses: [MailAddress]) -> [String] {
+        var result: [String] = []
+        for addr in mailAddresses {
+            if let addr = addr as? Mail_Address {
+                result.append(resolve(mail_address: addr))
+            } else if addr is CNMailAddressExtension {
+                result.append("CNMailAddress")
+            } else {
+                result.append("unknownMailAddressType")
+            }
+        }
+        return result
+    }
+
+    //get an pseudonym for a keyID
+    static func resolve(keyID: String) -> String {
+        if let key = DataHandler.handler.findKey(keyID: keyID) {
+            return key.pseudonym
+        }
+        return "noKeyID"
+    }
+
+    static func resolve(key: PersistentKey) -> String {
+        return key.pseudonym
+    }
+
+    static func resolve(keyIDs: [String]) -> [String] {
+        var result: [String] = []
+        for id in keyIDs {
+            result.append(resolve(keyID: id))
+        }
+        return result
+    }
+
+    static func saveToDisk(json: String, fileName: String = defaultFileName) {
+
+        if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
+
+            let fileURL = dir.appendingPathComponent(fileName)
+
+            if FileManager.default.fileExists(atPath: fileURL.path) {
+                // append
+                do {
+                    let fileHandle = try FileHandle(forUpdating: fileURL)
+
+                    fileHandle.seekToEndOfFile()
+                    if let encoded = "\n\(json),".data(using: .utf8) {
+                        fileHandle.write(encoded)
+                    }
+                    fileHandle.closeFile()
+                }
+                catch {
+                    print("Error while appending to logfile: \(error.localizedDescription)")
+                }
+            } else {
+                // write new
+                do {
+                    try json.write(to: fileURL, atomically: false, encoding: .utf8)
+                }
+                catch {
+                    print("Error while writing logfile: \(error.localizedDescription)")
+                }
+            }
+
+        }
+    }
+
+    static func sendLog(fileName: String = defaultFileName, logMailAddress: String = logReceiver) {
+
+        if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
+
+            let fileURL = dir.appendingPathComponent(fileName)
+
+            // reading
+            do {
+                let currentContent = try String(contentsOf: fileURL, encoding: .utf8)
+                if !currentContent.isEmpty {
+                    AppDelegate.getAppDelegate().mailHandler.send([logMailAddress], ccEntrys: [], bccEntrys: [], subject: "[Enzevalos] Log", message: "{\"studyID\":\"" + studyID + "\",\"data\":" + "[" + currentContent.dropLast() + "\n]" + "}", callback: sendCallback, loggingMail: true)
+                }
+            }
+            catch {
+                print("Error while reading logfile: \(error.localizedDescription)")
+            }
+        }
+    }
+
+    static func sendCallback(error: Error?) {
+        guard error == nil else {
+            print(error!)
+            return
+        }
+
+        clearLog()
+        let tmpNextDeadline = Date(timeIntervalSinceNow: TimeInterval(loggingInterval))
+        nextDeadline = tmpNextDeadline
+        UserManager.storeUserValue(nextDeadline as AnyObject?, attribute: Attribute.nextDeadline)
+    }
+
+    static func clearLog(fileName: String = defaultFileName) {
+        if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
+
+            let fileURL = dir.appendingPathComponent(fileName)
+
+            do {
+                try String().write(to: fileURL, atomically: false, encoding: .utf8)
+            }
+            catch {
+                print("Error while clearing logfile: \(error.localizedDescription)")
+            }
+        }
+    }
+}
diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift
index 64023b833fd1fbf8b02bfffc80e166bdd9f1ce10..ebc5e985cd789adebefe802f0878437d764b81ce 100644
--- a/enzevalos_iphone/MailHandler.swift
+++ b/enzevalos_iphone/MailHandler.swift
@@ -469,14 +469,15 @@ class MailHandler {
             completionCallback(MailServerConnectionError.NoData)
             return
         }
-        let requestKind = MCOIMAPMessagesRequestKind(rawValue: MCOIMAPMessagesRequestKind.headers.rawValue | MCOIMAPMessagesRequestKind.flags.rawValue)
-        let fetchOperation: MCOIMAPFetchMessagesOperation = self.IMAPSession!.fetchMessagesOperation(withFolder: folderPath, requestKind: requestKind, uids: uids)
-        fetchOperation.extraHeaders = MailHandler.extraHeaders
-
-        if uids.count() == 0 {
+        guard uids.count() > 0 else {
             completionCallback(nil)
             return
         }
+        // First fetch -> get flags
+        let requestKind = MCOIMAPMessagesRequestKind(rawValue: MCOIMAPMessagesRequestKind.headers.rawValue | MCOIMAPMessagesRequestKind.flags.rawValue)
+        let fetchOperation: MCOIMAPFetchMessagesOperation = self.IMAPSession!.fetchMessagesOperation(withFolder: folderPath, requestKind: requestKind, uids: uids)
+        fetchOperation.extraHeaders = MailHandler.extraHeaders
+        
         fetchOperation.start { (err, msg, vanished) -> Void in
             guard err == nil else {
                 let connerror = MailServerConnectionError.findErrorCode(error: err!)
@@ -488,7 +489,7 @@ class MailHandler {
                 let dispatchGroup = DispatchGroup()
                 for message in msgs.reversed() {
                     dispatchGroup.enter()
-                    let op = self.IMAPSession?.fetchParsedMessageOperation(withFolder: folderPath, uid: message.uid)
+                    let op = self.IMAPSession?.fetchMessageOperation(withFolder: folderPath, uid: message.uid)
                     op?.start { err, data in
                         guard err == nil else {
                             let connerror = MailServerConnectionError.findErrorCode(error: err!)
@@ -496,9 +497,9 @@ class MailHandler {
                             return
                         }
                         if let parser = data {
-                            let incomingMail = IncomingMail(rawData: parser.data(), uID: UInt64(message.uid), folderPath: folderPath, flags: message.flags)
+                            let id = UInt64(message.uid)
+                            let incomingMail = IncomingMail(rawData: parser, uID: id, folderPath: folderPath, flags: message.flags)
                             _ = incomingMail.store(keyRecord: record)
-
                         }
                         dispatchGroup.leave()
                     }
@@ -521,8 +522,6 @@ class MailHandler {
         }
     }
     
-    
-    
     public func getRepeals(for keyID: String) -> [Repeal] {
         let mails = DataHandler.handler.allMailsInFolder(key: keyID, contact: nil, folder: DataHandler.handler.findFolder(with: TravelHandler.keyManagementFolder), isSecure: true)
         var repeals: [Repeal] = []
@@ -973,65 +972,93 @@ class MailHandler {
             completionCallback(MailServerConnectionError.NoData)
             return
         }
-        let folderstatus = IMAPSession?.folderStatusOperation(folder.path)
-        folderstatus?.start { (error, status) -> Void in
-            guard error == nil else {
-                let conerror = MailServerConnectionError.findErrorCode(error: error!)
-                self.errorhandling(error: conerror, originalCall: {self.updateFolder(folder: folder, completionCallback: completionCallback)}, completionCallback: completionCallback)
-                self.IMAPSes = nil;
-                return
-            }
-            if let status = status {
-                let uidValidity = status.uidValidity
-                folder.uidvalidity = uidValidity
-                if let date = folder.lastUpdate {
-                    self.loadMailsSinceDate(folder: folder, since: date, completionCallback: completionCallback)
-                } else {
-                    if folder.path == UserManager.backendInboxFolderPath || folder.path.lowercased() == "INBOX".lowercased() {
-                        self.initInbox(inbox: folder, completionCallback: completionCallback)
-                    } else {
-                        self.initFolder(folder: folder, completionCallback: completionCallback)
-                    }
-                }
+        if folder.mailsOfFolder.count > 0 {
+            self.loadMailsByNum(folder: folder, completionCallback: completionCallback, multipleMails: false)
+        } else {
+            if folder.path == UserManager.backendInboxFolderPath || folder.path.lowercased() == "INBOX".lowercased() {
+                self.initInbox(inbox: folder, completionCallback: completionCallback)
+            } else {
+                self.initFolder(folder: folder, completionCallback: completionCallback)
             }
         }
     }
 
-    private func olderMails(folder: Folder, completionCallback: @escaping ((MailServerConnectionError?) -> ())) {
-        guard IMAPSession != nil else {
+    private func calculateIndicies(indicies: MCOIndexSet, folder: Folder, multipleMails: Bool) -> MCOIndexSet {
+        var factor = 1
+        if multipleMails {
+            factor = 3
+        }
+        let knownIds = folder.uids
+        let requestIds = indicies
+        requestIds.remove(knownIds)
+        let dif = requestIds.count() - UInt32(factor * MailHandler.MAXMAILS)
+        var range = MCORange(location: 0, length: UInt64(dif-1))
+        if dif > MailHandler.MAXMAILS {
+            requestIds.remove(range)
+        }
+        var lastMinElem = dif
+        while requestIds.count() < factor * MailHandler.MAXMAILS && lastMinElem > 0 {
+            lastMinElem = lastMinElem - UInt32(MailHandler.MAXMAILS)
+            range = MCORange(location: UInt64(lastMinElem), length: UInt64(MailHandler.MAXMAILS))
+            requestIds.add(range)
+            requestIds.remove(knownIds)
+            if folder.minID > UInt64(lastMinElem) {
+                folder.minID = UInt64(lastMinElem)
+            }
+        }
+        if lastMinElem < MailHandler.MAXMAILS {
+            range = MCORange(location: UInt64(1), length: UInt64(MailHandler.MAXMAILS))
+            requestIds.add(range)
+            folder.minID = 1
+        }
+        if multipleMails {
+            var (start, overflow) = folder.minID.subtractingReportingOverflow(UInt64(MailHandler.MAXMAILS))
+            if overflow && folder.minID > 1 {
+                // 1 < folder.min < MailHandler.MAXMAILs -> start with uid = 1
+                start = 1
+                overflow = false
+            }
+            if !overflow {
+                range = MCORange(location: start, length: UInt64(MailHandler.MAXMAILS))
+                requestIds.add(range)
+                folder.minID = start
+            }
+            
+        }
+        
+        return requestIds
+    }
+    
+    private func loadMailsByNum(folder: Folder, completionCallback: @escaping ((MailServerConnectionError?) -> ()), multipleMails: Bool) {
+        guard let session = IMAPSession else {
             completionCallback(MailServerConnectionError.NoData)
             return
         }
-        let folderPath = folder.path
-        if let mails = folder.mails {
-            var oldestDate: Date?
-            for m in mails {
-                if let mail = m as? PersistentMail {
-                    if oldestDate == nil || mail.date < oldestDate {
-                        oldestDate = mail.date
-                    }
+        let path = folder.path
+        if let statusOP = session.folderStatusOperation(path) {
+            statusOP.start{(error, status) -> Void in
+                guard error == nil else {
+                    let conerror = MailServerConnectionError.findErrorCode(error: error!)
+                    self.errorhandling(error: conerror, originalCall: {self.loadMailsByNum(folder: folder, completionCallback: completionCallback, multipleMails: multipleMails)}, completionCallback: completionCallback)
+                    self.IMAPSes = nil
+                    return
                 }
-            }
-            if let date = oldestDate {
-                let searchExp = MCOIMAPSearchExpression.search(before: date)
-                let searchOperation = self.IMAPSession?.searchExpressionOperation(withFolder: folderPath, expression: searchExp)
-                searchOperation?.start { (err, uids) -> Void in
-                    guard err == nil else {
-                        let conerror = MailServerConnectionError.findErrorCode(error: err!)
-                         self.errorhandling(error: conerror, originalCall: {self.olderMails(folder: folder, completionCallback: completionCallback)}, completionCallback: completionCallback)
-                        self.IMAPSes = nil
-                        return
-                    }
-                    if let ids = uids {
-                        //folder.lastUpdate = Date()
-                        self.loadMessagesFromServer(ids, folderPath: folderPath, record: nil, completionCallback: completionCallback)
-                    } else {
-                        completionCallback(nil)
-                    }
+                if let status = status, let ids = MCOIndexSet(range: MCORange(location: 0, length: UInt64(status.uidNext))) {
+                    let newIds = self.calculateIndicies(indicies: ids, folder: folder, multipleMails: multipleMails)
+                    self.loadMessagesFromServer(newIds, folderPath: path, record: nil, completionCallback: completionCallback)
                 }
-            } else {
-                initFolder(folder: folder, completionCallback: completionCallback)
             }
+        }
+        
+    }
+    
+    private func olderMails(folder: Folder, completionCallback: @escaping ((MailServerConnectionError?) -> ())) {
+        guard IMAPSession != nil else {
+            completionCallback(MailServerConnectionError.NoData)
+            return
+        }
+        if let mails = folder.mails, mails.count > 0 {
+            loadMailsByNum(folder: folder, completionCallback: completionCallback, multipleMails: true)
         } else {
             initFolder(folder: folder, completionCallback: completionCallback)
         }
@@ -1054,6 +1081,7 @@ class MailHandler {
             }
             if let ids = uids {
                 folder.lastUpdate = Date()
+                ids.remove(folder.uids)
                 self.loadMessagesFromServer(ids, folderPath: folderPath, maxLoad: maxLoad, record: nil, completionCallback: completionCallback)
             } else {
                 completionCallback(nil)
diff --git a/enzevalos_iphone/MailSession.swift b/enzevalos_iphone/MailSession.swift
index ded6896fddfdd498cc169295b2c22e5c350c5828..fba31f4e58e69a8c84cc7baff6e29e976e81ca83 100644
--- a/enzevalos_iphone/MailSession.swift
+++ b/enzevalos_iphone/MailSession.swift
@@ -35,7 +35,8 @@ class MailServer: Comparable {
         return lhs.sessionType == rhs.sessionType && lhs.hostname == rhs.hostname && lhs.port == rhs.port && lhs.connectionType == rhs.connectionType && lhs.authType == rhs.authType
     }
     
-    private static let maxWaitingSeconds = 12
+    private static let maxWaitingSeconds = 40
+    private var hasConnection = false
     
     let sessionType: SessionType
     var hostname: String
@@ -313,7 +314,10 @@ class MailServer: Comparable {
     
     private func startWaiting(){
         DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(MailServer.maxWaitingSeconds)) {
-            if !self.sendCallback && !self.works{
+            guard !self.hasConnection else {
+                return
+            }
+            if !self.sendCallback && !self.works {
                 self.sendCallback = true
                 self.callback(MailServerConnectionError.ConnectionError, self)
             }
@@ -335,6 +339,7 @@ class MailServer: Comparable {
                         }
                         return
                     }
+                    self.hasConnection = true
                     // No error: -> conntectionType is correct and server is reachable
                     if self.possibleAuthTypes.isEmpty {
                         self.possibleAuthTypes = MailSession.AUTHTYPE
@@ -357,11 +362,13 @@ class MailServer: Comparable {
                         // Observation: If the logger was not called -> connection type (e.g. startTLS, TLS) is wrong.
                         if !self.loggerCalled, let newType = self.toTestConnType.popFirst() {
                             self.connectionType = newType
+                            self.hasConnection = true
                             _ = self.findHost()
                         }
                         else if self.loggerCalled, let auth = self.possibleAuthTypes.last {
                             self.possibleAuthTypes.removeLast()
                             self.authType = auth
+                            self.hasConnection = true
                             _ = self.findHost()
                         }
                         else if self.toTestConnType.isEmpty {
@@ -369,6 +376,7 @@ class MailServer: Comparable {
                         }
                         return
                     }
+                    self.hasConnection = true
                     self.connectionType = session.connectionType
                     self.authType = session.authType
                     self.works = true
@@ -376,6 +384,7 @@ class MailServer: Comparable {
                         self.sendCallback = true
                         self.callback(nil, self)
                     }
+                    print("SMTP works!")
                 })
                 self.startWaiting()
                 return true
@@ -439,6 +448,7 @@ class MailServer: Comparable {
                         self.sendCallback = true
                         self.callback(nil, self)
                     }
+                    print("IMAP works!")
                 }
             })
         }
diff --git a/enzevalos_iphone/New Group/Mailbot.swift b/enzevalos_iphone/New Group/Mailbot.swift
index c43f5671218259843f4e6522a17e8fe991b9a529..d9408f7a15445251418fcddcd2089e71e1150cc8 100644
--- a/enzevalos_iphone/New Group/Mailbot.swift	
+++ b/enzevalos_iphone/New Group/Mailbot.swift	
@@ -44,7 +44,7 @@ class Mailbot {
     PS: Diese Nachricht wurde automatisch in Letterbox erzeugt und ist nur hier gespeichert.
     """
     
-    static let welcomeBody =
+    static let welcomeBodyDE =
     """
     Liebe Nutzerin, lieber Nutzer von Letterbox,
     
@@ -59,12 +59,32 @@ class Mailbot {
     """
     
     
+    static let welcomeBodyEn =
+    """
+    Hi,
+
+    Thank you for using and testing our app! This is a automatic generated mail and you can try to respond and test how to write a confidential mail. Our mail bot while response and you can get an impression about confidential communication.
+
+    We are interested inyour opinion, experience and impression of Letterbox. Maybe you can spend a couple of minuntes (less than 10 minutes) to fill out our online survey?
+    You can find our survey here: userpage.fu-berlin.de/~wieseoli/umfrage/limesurvey/index.php/952145?lang=en&id=\(StudySettings.studyID)
+    
+    When you participate in our survey you support our research and the development of confidential mail communication.
+    
+    We are happy about any question, comment or story on mail encryption or Letterbox. Just write us a (confidential) mail!
+
+    Thanks and best
+    Your Letterbox-mailbot Vic
+    
+    """
+    
+    
+    
     static func firstMail() {
         if !StudySettings.studyMode || !StudySettings.presentFirstQuestionaireMail {
             return
         }
-        let subject = "Herzlich Willkommen in Letterbox"
-        let body = welcomeBody
+        let subject = "Welcome to Letterbox"
+        let body = welcomeBodyEn
         
         mailToParticipat(subject: subject, body: body)
     }
diff --git a/enzevalos_iphone/Onboarding.swift b/enzevalos_iphone/Onboarding.swift
index 46495007e3fab530b8c45af7fe089ac33d4951bb..9298a83eb256bd34ead6366672fddb6b2f6f56cf 100644
--- a/enzevalos_iphone/Onboarding.swift
+++ b/enzevalos_iphone/Onboarding.swift
@@ -25,7 +25,6 @@ class Onboarding: NSObject {
     override init() {
         super.init()
     }
-
     static var textDelegate = TextFieldDelegate.init()
     static let defaultColor = UIColor.darkGray
     static let textColor = UIColor.white
@@ -59,7 +58,10 @@ class Onboarding: NSObject {
 
     static var credentialFails = 0
     static var testConfig = false
-    static var startTime: Date?
+    static var startTimeIMAPCheck: Date? //TODO What about SMTP?
+    
+    static var startTimeView = Date()
+    static var currentState = IntroState.Welcome
     static var showAuthType = false
     
     static var authTypeTest = 0
@@ -77,6 +79,7 @@ class Onboarding: NSObject {
     static func onboarding(_ errorCode: MailServerConnectionError? = nil) -> UIViewController {
         password.isSecureTextEntry = true
         doWhenDone = checkIMAPConfig
+        startTimeView = Date()
 
         //Background
         var myBounds = CGRect()
@@ -130,8 +133,12 @@ class Onboarding: NSObject {
         intro2.iconImageView.image = UIGraphicsGetImageFromCurrentImageContext()!
         UIGraphicsEndImageContext()
         intro2.bodyLabel.textAlignment = NSTextAlignment.left
-        intro2.bodyLabel.textColor = UIColor.black
-        intro2.titleLabel.textColor = UIColor.black
+        
+        if ThemeManager.unencryptedMessageColor() != ThemeManager.defaultColor {
+            intro2.bodyLabel.textColor = UIColor.black
+            intro2.titleLabel.textColor = UIColor.black
+        }
+        
 
         let path = Bundle.main.path(forResource: "videoOnboarding2", ofType: "m4v")
         let url = URL.init(fileURLWithPath: path!)
@@ -217,7 +224,10 @@ class Onboarding: NSObject {
 
         intro2.viewWillAppearBlock = {
             UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions.curveEaseIn, animations: {
-                vc?.view.backgroundColor = ThemeManager.unencryptedMessageColor()
+                let bgColor = ThemeManager.unencryptedMessageColor()
+                if bgColor != ThemeManager.defaultColor {
+                    vc?.view.backgroundColor = bgColor
+                }
                 vc?.view.setNeedsDisplay()
             })
         }
@@ -225,28 +235,48 @@ class Onboarding: NSObject {
             UIView.animate(withDuration: duration, delay: 0.05, options: UIView.AnimationOptions.curveEaseIn, animations: {
                 if (vc?.view.backgroundColor != ThemeManager.encryptedMessageColor()) {
                     vc?.view.backgroundColor = defaultColor
-                    vc?.view.setNeedsDisplay()
                 }
+                vc?.view.setNeedsDisplay()
             })
         }
         intro1.viewWillAppearBlock = {
-            UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions.curveEaseIn, animations: { vc?.view.backgroundColor = ThemeManager.encryptedMessageColor(); vc?.view.setNeedsDisplay() })
+            UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions.curveEaseIn, animations: {
+                let bgColor = ThemeManager.encryptedMessageColor()
+                if bgColor != ThemeManager.defaultColor {
+                    vc?.view.backgroundColor = bgColor
+                }
+                vc?.view.setNeedsDisplay()
+            })
         }
         intro1.viewWillDisappearBlock = {
             UIView.animate(withDuration: duration, delay: 0.05, options: UIView.AnimationOptions.curveEaseIn, animations: {
                 if (vc?.view.backgroundColor != ThemeManager.unencryptedMessageColor()) {
                     vc?.view.backgroundColor = defaultColor
-                    vc?.view.setNeedsDisplay()
                 }
+                vc?.view.setNeedsDisplay()
             })
         }
 
         loginViewController = vc!
         vc?.pageChanged = {(oldPage:Int, newPage: Int) -> () in
             password.isSecureTextEntry = true
-            Logger.log(onboardingPageTransition: oldPage, to: newPage, onboardingSection: "intro")
+            var nextState = IntroState.Welcome
+            switch newPage {
+            case 0:
+                nextState = .Welcome
+            case 1:
+                nextState = .ConfidentialExplanation
+            case 2:
+                nextState = .NotConfidentialExplanation
+            case 3:
+                nextState = .ReminderIcon
+            default:
+                nextState = .BriefInput
+            }
+            self.changeState(newState: nextState)
+            //Logger.log(onboardingPageTransition: oldPage, to: newPage, onboardingSection: "intro")
         }
-        Logger.log(onboardingState: "intro")
+        //Logger.log(onboardingState: "intro")
         return vc!
     }
 
@@ -273,7 +303,8 @@ class Onboarding: NSObject {
         let vc = Onboard.OnboardingViewController(backgroundImage: background, contents: [page1])!
         vc.pageControl = UIPageControl.init()
         vc.view.backgroundColor = defaultColor
-            Logger.log(onboardingState: "checkServerConfig")
+        self.changeState(newState: .UseraddressDetail)
+        //Logger.log(onboardingState: "checkServerConfig")
         return vc
     }
 
@@ -288,7 +319,8 @@ class Onboarding: NSObject {
         let vc = Onboard.OnboardingViewController(backgroundImage: background, contents: [page1])
         vc?.pageControl = UIPageControl.init()
         vc?.view.backgroundColor = defaultColor
-        Logger.log(onboardingState: "keyHandling")
+        changeState(newState: .GenerateKey)
+        //Logger.log(onboardingState: "keyHandling")
         return vc!
     }
     //UI Definition
@@ -523,9 +555,31 @@ class Onboarding: NSObject {
         let vc = Onboard.OnboardingViewController(backgroundImage: background, contents: contents)
         vc?.view.backgroundColor = defaultColor
         vc?.pageChanged = {(oldPage:Int, newPage: Int) -> () in
-                Logger.log(onboardingPageTransition: oldPage, to: newPage, onboardingSection: "detail")
+            var nextState = IntroState.Failed
+            switch newPage {
+            case 0:
+                nextState = IntroState.Failed
+            case 1:
+                nextState = IntroState.UseraddressDetail
+            case 2:
+                nextState = IntroState.UsernameDetail
+            case 3:
+                nextState = IntroState.IMAP
+            case 4:
+                nextState = IntroState.IMAPCon
+            case 5:
+                nextState = IntroState.SMTP
+            case 6:
+                nextState = IntroState.SMTPCon
+            case 7:
+                nextState = IntroState.EndDetail
+            default:
+                nextState = IntroState.Failed
+            }
+            changeState(newState: nextState)
+            //Logger.log(onboardingPageTransition: oldPage, to: newPage, onboardingSection: "detail")
         }
-        Logger.log(onboardingState: "detail")
+        //Logger.log(onboardingState: "detail")
         
         return vc!
     }
@@ -541,7 +595,8 @@ class Onboarding: NSObject {
         let vc = Onboard.OnboardingViewController(backgroundImage: background, contents: [page1])!
         vc.pageControl = UIPageControl.init()
         vc.view.backgroundColor = defaultColor
-            Logger.log(onboardingState: "contact")
+        changeState(newState: .ContactAccess)
+        //Logger.log(onboardingState: "contact")
         return vc
     }
 
@@ -660,7 +715,7 @@ class Onboarding: NSObject {
         let mailSession = setIMAPSession()
         if let imap = previousIMAP, MailServerConnectionError.wrongServerConfig(errors: imap.errors) && Onboarding.credentialFails == 2 && !mailSession.hasJsonFile && mailSession.startLongSearchOfServerConfig(hostFromAdr: true) {
             testConfig = true
-            startTime = Date()
+            startTimeIMAPCheck = Date()
         }
         else if isDetailedOnboarding{
             checkDetailConfig(imap: true)
@@ -669,11 +724,11 @@ class Onboarding: NSObject {
         else {
             if mailSession.startTestingServerConfigFromList() {
                 testConfig = true
-                startTime = Date()
+                startTimeIMAPCheck = Date()
             }
             else if mailSession.startLongSearchOfServerConfig(hostFromAdr: !isDetailedOnboarding){
                 testConfig = true
-                startTime = Date()
+                startTimeIMAPCheck = Date()
             }
             else {
                 Onboarding.credentialFails = 3
@@ -697,6 +752,7 @@ class Onboarding: NSObject {
         guard testConfig == false else {
             return
         }
+        startTimeIMAPCheck = nil
         let mailSession = setSMTPSession()
         let isDetailedOnboarding = Onboarding.credentialFails >= 3
         if let smtp = previousSMTP, MailServerConnectionError.wrongServerConfig(errors: smtp.errors) && Onboarding.credentialFails == 2 && !mailSession.hasJsonFile && mailSession.startLongSearchOfServerConfig(hostFromAdr: !isDetailedOnboarding) {
@@ -723,8 +779,13 @@ class Onboarding: NSObject {
     
     static func imapCompletion(imapWorks: Bool) {
         testConfig = false
-        if let start = startTime {
-            startTime = nil
+        if imapWorks {
+            _ = currentIMAP?.storeToUserDefaults()
+            checkSMTPConfig()
+            return
+        }
+        else if let start = startTimeIMAPCheck {
+            startTimeIMAPCheck = nil
             let duration = start.timeIntervalSinceNow
             if duration < TimeInterval(-10) {
                 Onboarding.credentialFails = 3
@@ -732,11 +793,6 @@ class Onboarding: NSObject {
                 return
             }
         }
-        if imapWorks {
-            _ = currentIMAP?.storeToUserDefaults()
-            checkSMTPConfig()
-            return
-        }
         else {
             Onboarding.credentialFails += 1
             checkIMAPConfigUI()
@@ -774,6 +830,12 @@ class Onboarding: NSObject {
         }
         return keys
     }
+    private static func changeState(newState: IntroState) {
+        let duration = Date().timeIntervalSince(startTimeView)
+        startTimeView = Date()
+        Logger.log(onboardingState: currentState, duration: duration)
+        currentState = newState
+    }
 }
 
 
@@ -859,6 +921,8 @@ extension PickerDataDelegate: UIPickerViewDelegate {
     func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
         pickedValue = rows[row]
     }
+    
+    
 }
 
 class Listener: MailSessionListener {
@@ -879,3 +943,48 @@ class Listener: MailSessionListener {
         })
     }
 }
+
+enum IntroState {
+    case Welcome, ConfidentialExplanation, NotConfidentialExplanation, ReminderIcon, BriefInput, GoogleLogIn, Failed, UseraddressDetail, UsernameDetail, IMAP, IMAPCon, SMTP, SMTPCon, EndDetail, GenerateKey, ContactAccess, Finish
+    
+    var name: String {
+        get {
+            switch self {
+            case .Welcome:
+                return "Welcome"
+            case .ConfidentialExplanation:
+                return "confidentialSlide"
+            case .NotConfidentialExplanation:
+                return "notConfidentialSlide"
+            case .ReminderIcon:
+                return "animationSlide"
+            case .BriefInput:
+                return "briefInputSlide"
+            case .IMAP:
+                return "imapSlide"
+            case .IMAPCon:
+                return "imapConnTypeSlide"
+            case .SMTP:
+                return "smtpSlide"
+            case .SMTPCon:
+                return "smtpConnTypeSlide"
+            case .UseraddressDetail:
+                return "useraddressDetailSlide"
+            case .EndDetail:
+                return "endDetailSlide"
+            case .GoogleLogIn:
+                return "GoogleLoginSlide"
+            case .Failed:
+                return "FailedSlide"
+            case .UsernameDetail:
+                return "UserNameDetailSlide"
+            case .GenerateKey:
+                return "GenerateKeySlide"
+            case .ContactAccess:
+                return "ContactAccessSlide"
+            case .Finish:
+                return "Finish"
+            }
+        }
+    }
+}
diff --git a/enzevalos_iphone/OutgoingMail.swift b/enzevalos_iphone/OutgoingMail.swift
index c79f973ab8c53cb39141c2a6c57e582fe5663066..f37ededec8a637a2c5a7f87c1dfb1ce1fe788fbd 100644
--- a/enzevalos_iphone/OutgoingMail.swift
+++ b/enzevalos_iphone/OutgoingMail.swift
@@ -24,7 +24,7 @@ class OutgoingMail {
     private let ccEntrys: [MCOAddress]
     private let bccEntrys: [MCOAddress]
     var username = UserManager.loadUserValue(Attribute.accountname) as? String ?? ""
-    var useraddr = UserManager.loadUserValue(Attribute.userAddr) as? String ?? ""
+    var useraddr = (UserManager.loadUserValue(Attribute.userAddr) as? String ?? "").lowercased()
     var userDisplayName = UserManager.loadUserValue(Attribute.userDisplayName) as? String
     
     var sender: MCOAddress {
diff --git a/enzevalos_iphone/ReadViewController.swift b/enzevalos_iphone/ReadViewController.swift
index 29f8236717b0564f93d9d1f7bdb42fe3eac564ba..543632fb25975c1d6a878c9aaec50fd4770d6ca3 100644
--- a/enzevalos_iphone/ReadViewController.swift
+++ b/enzevalos_iphone/ReadViewController.swift
@@ -59,7 +59,8 @@ class ReadViewController: UITableViewController {
     var keyDiscoveryDate: Date? = nil
     
     var secretKeyPasswordField: UITextField? = nil
-
+    var infoState = LogData.WarningType.none
+    
     var isNewPubKey: Bool? {
         guard let mail = mail, let signedKey = mail.signedKey else {
             return nil
@@ -191,7 +192,6 @@ class ReadViewController: UITableViewController {
 
     override func willMove(toParent parent: UIViewController?) {
         super.willMove(toParent: parent)
-
         if parent == nil {
             UIView.animate(withDuration: 0.3, animations: { self.navigationController?.navigationBar.barTintColor = ThemeManager.defaultColor })
         }
@@ -320,6 +320,7 @@ class ReadViewController: UITableViewController {
             performSegue(withIdentifier: "answerTo", sender: "reactButton")
         }
         Logger.log(reactTo: mail)
+        Logger.log(reactWarning: infoState, reaction: .clickButton)
     }
 
     @IBAction func markUnreadButton(_ sender: AnyObject) {
@@ -352,38 +353,50 @@ class ReadViewController: UITableViewController {
         if let m = mail {
             let alert: UIAlertController
             let url: String
+            let opening = Date()
+            var icon = LogData.IndicatorButton.notConfidential
+            
             if m.trouble {
                 alert = UIAlertController(title: NSLocalizedString("LetterDamaged", comment: "Modified email received")/*"Angerissener Brief"*/, message: NSLocalizedString("ReceiveDamagedInfo", comment: "Modefied email infotext"), preferredStyle: .alert)
                 url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapseTorn"
+                icon = .error
             } else if m.isSecure {
                 alert = UIAlertController(title: NSLocalizedString("Letter", comment: "letter label"), message: NSLocalizedString("ReceiveSecureInfo", comment: "Letter infotext"), preferredStyle: .alert)
                 url = "https://userpage.fu-berlin.de/letterbox/faq.html#secureMailAnswer"
+                icon = .confidential
                 alert.addAction(UIAlertAction(title: NSLocalizedString("ReadMailOnOtherDevice", comment: "email is not readable on other devices"), style: .default, handler: { (action: UIAlertAction!) -> Void in
-                        Logger.log(close: url, mail: m, action: "exportKey")
+                        let duration = Date().timeIntervalSince(opening)
+                        Logger.log(close: icon, mail: m, action: .exportKey, duration: duration)
                         self.performSegue(withIdentifier: "exportKeyFromReadView", sender: nil)
                     }))
             } else if m.isCorrectlySigned {
                 alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfoVerified", comment: "Postcard infotext"), preferredStyle: .alert)
                 url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapsePostcard"
+                icon = .signedOnly
             } else if m.isEncrypted && !m.unableToDecrypt {
                 //TODO: maybe add travel hook here
+                icon = .encryptedOnly
                 alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfoEncrypted", comment: "Postcard infotext"), preferredStyle: .alert)
                 url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapsePostcard"
             } else if m.isEncrypted && m.unableToDecrypt {
                 //TODO: add travel hook here
+                icon = .unableToDecrypt
                 alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfoDecryptionFailed", comment: "Postcard infotext"), preferredStyle: .alert)
                 url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapseBeginPGP"
             } else {
+                icon = .notConfidential
                 alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfo", comment: "Postcard infotext"), preferredStyle: .alert)
                 url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapsePostcard"
             }
             Logger.log(open: url, mail: m)
             alert.addAction(UIAlertAction(title: NSLocalizedString("MoreInformation", comment: "More Information label"), style: .default, handler: { (action: UIAlertAction!) -> Void in
-                    Logger.log(close: url, mail: m, action: "openURL")
+                    let duration = Date().timeIntervalSince(opening)
+                    Logger.log(close: icon, mail: m, action: .moreInfo, duration: duration)
                     UIApplication.shared.openURL(URL(string: url)!)
                 }))
             alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { (action: UIAlertAction!) -> Void in
-                Logger.log(close: url, mail: m, action: "OK")
+                let duration = Date().timeIntervalSince(opening)
+                Logger.log(close: icon, mail: m, action: .close, duration: duration)
             }))
             DispatchQueue.main.async(execute: {
                 self.present(alert, animated: true, completion: nil)
@@ -465,9 +478,6 @@ class ReadViewController: UITableViewController {
             messageBody.text = messageBody.text?.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines).appending("\n")
 
             // NavigationBar Icon
-            let iconView = UIImageView()
-            iconView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
-            iconView.contentMode = .scaleAspectFit
             var icon: UIImage
             if mail.trouble {
                 icon = StudySettings.securityIndicator.imageOfCorruptedIndicator()
@@ -478,13 +488,20 @@ class ReadViewController: UITableViewController {
             } else {
                 icon = StudySettings.securityIndicator.imageOfInsecureIndicator()
             }
-            iconView.image = icon
+            
+            let iconView = UIImageView(image: icon)
+            iconView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+            iconView.contentMode = .scaleAspectFit
             iconButton.setImage(icon, for: UIControl.State())
-
+            // Set color of icon
+            iconButton.tintColor = iconView.tintColor
+            
+            infoState = LogData.WarningType.none
             // Mail info text
             if mail.trouble {
+                infoState = .error
                 infoSymbol.text = "!"
-                infoSymbol.textColor = ThemeManager.troubleMessageColor()
+                infoSymbol.textColor = ThemeManager.red
                 infoHeadline.text = NSLocalizedString("corruptedHeadline", comment: "This mail is corrupted")
                 infoHeadline.textColor = UIColor.black
                 infoText.text = NSLocalizedString("corruptedText", comment: "This mail is corrupted")
@@ -493,40 +510,48 @@ class ReadViewController: UITableViewController {
                 infoCell.translatesAutoresizingMaskIntoConstraints = true
             } else if mail.isEncrypted && mail.unableToDecrypt {
                 if TravelHandler.instance().mode != .atHome {
+                    infoState = .unableToDecryptTravel
                     infoSymbol.text = "?"
-                    infoSymbol.textColor = ThemeManager.unencryptedMessageColor()
+                    infoSymbol.textColor = ThemeManager.orange
                     infoHeadline.text = NSLocalizedString("couldNotDecryptTravelHeadline", comment: "Message could not be decrypted")
                     infoHeadline.textColor = UIColor.gray
                     infoText.text = NSLocalizedString("couldNotDecryptTravelText", comment: "Message could not be decrypted")
                 } else {
                     //TODO: add travel hook here
+                    infoState = .unableToDecrypt
                     infoSymbol.text = "?"
-                    infoSymbol.textColor = ThemeManager.unencryptedMessageColor()
+                    infoSymbol.textColor = ThemeManager.orange
                     infoHeadline.text = NSLocalizedString("couldNotDecryptHeadline", comment: "Message could not be decrypted")
                     infoHeadline.textColor = UIColor.gray
                     infoText.text = NSLocalizedString("couldNotDecryptText", comment: "Message could not be decrypted")
 
                 }
             } else if (isNewPubKey ?? false) && !deletedWhileTravel {
+                infoState = .newKey
                 infoSymbol.text = "!"
-                infoSymbol.textColor = ThemeManager.unencryptedMessageColor()
+                infoSymbol.textColor = ThemeManager.orange
                 infoHeadline.text = NSLocalizedString("newKeyHeadline", comment: "Message contained a new public key")
                 infoHeadline.textColor = UIColor.gray
                 infoText.text = NSLocalizedString("newKeyText", comment: "Message contained a new public key")
             } else if mail.from.hasKey && !mail.isSecure {
                 //TODO: add travel hook here
+                infoState = .notConfidential
                 infoSymbol.text = "?"
                 infoSymbol.textColor = ThemeManager.unencryptedMessageColor()
                 infoHeadline.text = NSLocalizedString("encryptedBeforeHeadline", comment: "The sender has encrypted before")
                 infoHeadline.textColor = UIColor.gray
                 infoText.text = NSLocalizedString("encryptedBeforeText", comment: "The sender has encrypted before")
             } else if deletedWhileTravel {
+                infoState = .deletedWhileTravel
                 infoSymbol.text = "!"
-                infoSymbol.textColor = ThemeManager.encryptedMessageColor()
+                infoSymbol.textColor = ThemeManager.green
                 infoHeadline.text = NSLocalizedString("unreadableWhileTravelHeadline", comment: "The mail is not readable while traveling")
                 infoHeadline.textColor = UIColor.gray
                 infoText.text = NSLocalizedString("unreadableWhileTravelText", comment: "The mail is not readable while traveling")
             }
+            if infoState != .none {
+                Logger.log(warning: infoState)
+            }
         }
     }
 
diff --git a/enzevalos_iphone/SendViewController.swift b/enzevalos_iphone/SendViewController.swift
index 06ebc37462870f1a0f82eb69d2e3c1fe89236fa6..ea331c0bc08f55e05d428804f6c1353ed6ab1818 100644
--- a/enzevalos_iphone/SendViewController.swift
+++ b/enzevalos_iphone/SendViewController.swift
@@ -50,7 +50,7 @@ class SendViewController: UIViewController {
     @IBOutlet weak var scrollViewBottom: NSLayoutConstraint!
     @IBOutlet weak var scrollviewRecognizer: UITapGestureRecognizer!
     @IBOutlet weak var sendButton: UIBarButtonItem!
-
+    
     var keyboardOpened = false
     var keyboardY: CGFloat = 0
     var keyboardHeight: CGFloat = 0
@@ -137,8 +137,14 @@ class SendViewController: UIViewController {
 
         subjectText.toLabelText = NSLocalizedString("Subject", comment: "subject label") + ": "
 
-        let iconView = AnimatedSendIcon()
-        iconView.frame = iconView.frame.offsetBy(dx: 0, dy: -10)
+        var iconView: SendIcon & UIView = SimpleSendIcon()
+        if StudySettings.showBothSecurityIconsInSend {
+            iconView = AnimatedSendIcon()
+            iconView.frame = iconView.frame.offsetBy(dx: 0, dy: -10)
+        }
+        else {
+            iconView.frame = iconView.frame.offsetBy(dx: 10, dy: 0)
+        }
         iconButton.addSubview(iconView)
 
         toText.delegate = dataDelegate
@@ -662,7 +668,7 @@ class SendViewController: UIViewController {
     func animateIfNeeded() {
         var uiSecurityState: SendViewMailSecurityState = .letter
         
-        if let view = iconButton.subviews.first as? AnimatedSendIcon, view.isPostcardOnTop {
+        if let view = iconButton.subviews.first as? SendIcon, view.isPostcardOnTop {
             uiSecurityState = .postcard
         }
         
@@ -684,7 +690,7 @@ class SendViewController: UIViewController {
     }
 
     func startIconAnimation() {
-        if let view = iconButton.subviews.first as? AnimatedSendIcon {
+        if let view = iconButton.subviews.first as? SendIcon {
             view.switchIcons()
         }
     }
@@ -693,8 +699,11 @@ class SendViewController: UIViewController {
         let alert: UIAlertController
         let url: String
         let travelMode = TravelHandler.instance().mode
+        var icon = LogData.IndicatorButton.notConfidential
+        let opening = Date()
         if mailSecurityState != .letter && travelMode != .borderCrossing {
             alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "Postcard label"), message: enforcePostcard ? NSLocalizedString("SendInsecureInfoAll", comment: "Postcard infotext") : NSLocalizedString("SendInsecureInfo", comment: "Postcard infotext"), preferredStyle: .alert)
+            icon = .notConfidential
             url = "https://userpage.fu-berlin.de/letterbox/faq.html#headingPostcard"
             if subjectText.inputText() != NSLocalizedString("inviteSubject", comment: "") && !UserDefaults.standard.bool(forKey: "hideFreeTextInvitation") {
                 alert.addAction(UIAlertAction(title: freeTextInviationTitle, style: .default, handler: {
@@ -709,8 +718,8 @@ class SendViewController: UIViewController {
                             self.showHelpDialog()
                         }
                     }
-
-                    Logger.log(close: url, mail: nil, action: "invitationButton in mode \(StudySettings.invitationsmode)")
+                    let duration = Date().timeIntervalSince(opening)
+                    Logger.log(close: icon, mail: nil, action: .inviteOther, duration: duration)
                 }))
             }
         } else if travelMode == .borderCrossing {
@@ -719,24 +728,42 @@ class SendViewController: UIViewController {
             alert.addAction(UIAlertAction(title: NSLocalizedString("BorderCrossed", comment: "The user has passed the border"), style: .default, handler: {
                 (action: UIAlertAction) -> Void in
                 let travelHandler = TravelHandler.instance()
-                Logger.log(close: url, mail: nil, action: "travelmode follow-up")
+                let duration = Date().timeIntervalSince(opening)
+                Logger.log(close: icon, mail: nil, action: .travelFollowUp, duration: duration)
                 self.navigationController?.navigationBar.barTintColor = ThemeManager.defaultColor
                 self.navigationController?.pushViewController(travelHandler.getUI(current: self), animated: true)
             }))
         } else {
             alert = UIAlertController(title: NSLocalizedString("Letter", comment: "Letter label"), message: NSLocalizedString("SendSecureInfo", comment: "Letter infotext"), preferredStyle: .alert)
             url = "https://userpage.fu-berlin.de/letterbox/faq.html#secureMail"
+            icon = .confidential
         }
         if recipientSecurityState != .allInsecure && travelMode != .borderCrossing {
+            icon = .notConfidential
             if enforcePostcard {
-                alert.addAction(UIAlertAction(title: recipientSecurityState == .allInsecure || recipientSecurityState == .mixed ? NSLocalizedString("sendSecureIfPossible", comment: "This mail should be send securely to people with keys") : NSLocalizedString("sendSecure", comment: "This mail should be send securely"), style: .default, handler: { (action: UIAlertAction!) -> Void in
-                    Logger.log(close: url, mail: nil, action: "sendSecureIfPossible")
+                var title = NSLocalizedString("sendSecure", comment: "This mail should be send securely")
+                var actionType = LogData.UserInteractionPopUp.EnableEnforceConf
+                if recipientSecurityState == .allInsecure || recipientSecurityState == .mixed {
+                    title = NSLocalizedString("sendSecureIfPossible", comment: "This mail should be send securely to people with keys")
+                    actionType = .DisableEnforceConf
+                }
+                alert.addAction(UIAlertAction(title: title , style: .default, handler: { (action: UIAlertAction!) -> Void in
+                    let duration = Date().timeIntervalSince(opening)
+                    Logger.log(close: icon, mail: nil, action: actionType, duration: duration)
                     self.enforcePostcard = false
                     DispatchQueue.main.async { self.updateSecurityUI() }
                 }))
             } else {
-                alert.addAction(UIAlertAction(title: recipientSecurityState == .allInsecure || recipientSecurityState == .mixed ? NSLocalizedString("sendInsecureAll", comment: "This mail should be send insecurely to everyone, including contacts with keys") : NSLocalizedString("sendInsecure", comment: "This mail should be send insecurely"), style: .default, handler: { (action: UIAlertAction!) -> Void in
-                    Logger.log(close: url, mail: nil, action: "sendInsecure")
+                icon = .confidential
+                var title = NSLocalizedString("sendInsecure", comment: "This mail should be send insecurely")
+                var actionType = LogData.UserInteractionPopUp.disableConf
+                if recipientSecurityState == .allInsecure || recipientSecurityState == .mixed {
+                    title = NSLocalizedString("sendInsecureAll", comment: "This mail should be send insecurely to everyone, including contacts with keys")
+                    actionType = .enableConf
+                }
+                alert.addAction(UIAlertAction(title: title, style: .default, handler: { (action: UIAlertAction!) -> Void in
+                    let duration = Date().timeIntervalSince(opening)
+                    Logger.log(close: icon, mail: nil, action: actionType, duration: duration)
                     self.enforcePostcard = true
                     DispatchQueue.main.async { self.updateSecurityUI() }
                 }))
@@ -744,11 +771,13 @@ class SendViewController: UIViewController {
         }
         Logger.log(open: url, mail: nil)
         alert.addAction(UIAlertAction(title: NSLocalizedString("MoreInformation", comment: "More Information label"), style: .default, handler: { (action: UIAlertAction!) -> Void in
-            Logger.log(close: url, mail: nil, action: "openURL")
+            let duration = Date().timeIntervalSince(opening)
+            Logger.log(close: icon, mail: nil, action: .moreInfo, duration: duration)
             UIApplication.shared.openURL(URL(string: url)!)
         }))
         alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { (action: UIAlertAction!) -> Void in
-            Logger.log(close: url, mail: nil, action: "OK")
+            let duration = Date().timeIntervalSince(opening)
+            Logger.log(close: icon, mail: nil, action: .close, duration: duration)
         }))
         DispatchQueue.main.async(execute: {
             self.present(alert, animated: true, completion: nil)
diff --git a/enzevalos_iphone/SimpleSendIcon.swift b/enzevalos_iphone/SimpleSendIcon.swift
new file mode 100644
index 0000000000000000000000000000000000000000..2d796f2bfea0aa27ff85e526a82447bed34993fa
--- /dev/null
+++ b/enzevalos_iphone/SimpleSendIcon.swift
@@ -0,0 +1,66 @@
+//
+//  SimpleSendIcon.swift
+//  enzevalos_iphone
+//
+//  Created by Oliver on 13.04.2019.
+//  Copyright © 2018 fu-berlin.
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+//
+//  RezisingBehavior taken from PaintCode generated file
+
+import Foundation
+import UIKit
+
+protocol SendIcon {
+    func switchIcons()
+    var isPostcardOnTop: Bool {
+        get
+    }
+}
+
+class SimpleSendIcon: UIView, SendIcon {
+    var isPostcardOnTop = false
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        setIcon(toLetter: true)
+    }
+    required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    private func setIcon(toLetter: Bool) {
+        for subView in self.subviews {
+            self.willRemoveSubview(subView)
+            subView.removeFromSuperview()
+        }
+        var icon = StudySettings.securityIndicator.imageOfSecureIndicator(button: true)
+        isPostcardOnTop = false
+        if !toLetter {
+            // move to secure state
+            isPostcardOnTop = true
+            icon = StudySettings.securityIndicator.imageOfInsecureIndicator(button: true)
+        }
+        
+        let iconView = UIImageView(image: icon)
+        iconView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+        iconView.contentMode = .scaleAspectFit
+        self.addSubview(iconView)
+        self.reloadInputViews()
+    }
+    
+    func switchIcons() {
+        setIcon(toLetter: isPostcardOnTop)
+    }
+}
diff --git a/enzevalos_iphone/StudySettings.swift b/enzevalos_iphone/StudySettings.swift
index 3280c3d7145a8218a1d4e115a249f55e2cf01481..c0060e09396610253be2ee04f448ffa843e876f0 100644
--- a/enzevalos_iphone/StudySettings.swift
+++ b/enzevalos_iphone/StudySettings.swift
@@ -37,6 +37,7 @@ class StudySettings {
     }
 
     static var presentFirstQuestionaireMail = false
+    static var showBothSecurityIconsInSend = false
     
     static var securityIndicator: SecurityIndicator = SecurityIndicator.load() as! SecurityIndicator
     static var invitationsmode: Inviation = Inviation.load() as! Inviation
@@ -74,14 +75,15 @@ class StudySettings {
             Logger.logging = false
             return
         }
+        else {
+            Logger.logging = true
+        }
         if UserDefaults.standard.string(forKey: "studyID") != nil && UserDefaults.standard.string(forKey: "hideWarnings") != nil { //no need to refill this fields, they are already loaded
             return
         }
-        Logger.logging = true
         let keychain = Keychain(service: "Enzevalos/Study")
         if let studyID = keychain["studyID"] {
             UserDefaults.standard.set(studyID, forKey: "studyID")
-            Logger.studyID = studyID
         } else {
             let studyID = String.random(length: 30)
             presentFirstQuestionaireMail = true
@@ -99,7 +101,7 @@ class StudySettings {
     }
 
     public static func setupStudyKeys() {
-        if studyMode || Logger.logging {
+        if studyMode {
             setupStudyPublicKeys()
         }
     }
diff --git a/enzevalos_iphone/StyleKits/IconsStyleKit.swift b/enzevalos_iphone/StyleKits/IconsStyleKit.swift
index 26c2b7810bb7e41bc03709b15cecdac6981fe84a..e04466625d767dc82f1433a6fd632aeca3114f50 100644
--- a/enzevalos_iphone/StyleKits/IconsStyleKit.swift
+++ b/enzevalos_iphone/StyleKits/IconsStyleKit.swift
@@ -19,20 +19,25 @@ internal class IconsStyleKit: NSObject {
 
     private struct Cache {
         static let strokeColor: UIColor = UIColor(red: 0.000, green: 0.000, blue: 0.000, alpha: 1.000)
+        static let buttonStrokeColor: UIColor = UIView().tintColor
         static var imageOfLetter: UIImage?
         static var imageOfLetterBG: UIImage?
+        static var imageOfLetterButton: UIImage?
         static var letterTargets: [AnyObject]?
         static var imageOfLetterCorrupted: UIImage?
         static var letterCorruptedTargets: [AnyObject]?
         static var imageOfPostcard: UIImage?
+        static var imageOfPostcardButton: UIImage?
         static var imageOfPostcardBG: UIImage?
         static var postcardTargets: [AnyObject]?
         static var imageOfLetterOpen: UIImage?
         static var letterOpenTargets: [AnyObject]?
         static var imageOfPadlockSecure: UIImage?
+        static var imageOfPadlockSecureButton: UIImage?
         static var imageOfPadlockSecureBG: UIImage?
         static var padlockSecureTargets: [AnyObject]?
         static var imageOfPadlockInsecure: UIImage?
+        static var imageOfPadlockInsecureButton: UIImage?
         static var imageOfPadlockInsecureBG: UIImage?
         static var padlockInsecureTargets: [AnyObject]?
         static var imageOfPadlockError: UIImage?
@@ -214,7 +219,6 @@ internal class IconsStyleKit: NSObject {
     @objc open dynamic class func drawPostcard(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 49, height: 34), resizing: ResizingBehavior = .aspectFit, color: UIColor = IconsStyleKit.strokeColor, fillBackground: Bool = false) {
         //// General Declarations
         let context = UIGraphicsGetCurrentContext()!
-
         //// Resize to Target Frame
         context.saveGState()
         let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 49, height: 34), target: targetFrame)
@@ -525,7 +529,6 @@ internal class IconsStyleKit: NSObject {
         context.restoreGState()
         
         context.restoreGState()
-        
     }
     
     @objc dynamic public class func drawPadlockInsecure(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 35, height: 50), resizing: ResizingBehavior = .aspectFit, color: UIColor = strokeColor, fillBackground: Bool = false) {
@@ -608,9 +611,7 @@ internal class IconsStyleKit: NSObject {
     @objc dynamic public class func drawPadlockError(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 35, height: 50), resizing: ResizingBehavior = .aspectFit, color: UIColor = strokeColor, fillBackground: Bool = false) {
         //// General Declarations
         let context = UIGraphicsGetCurrentContext()!
-        
        
-        
         //// Resize to Target Frame
         context.saveGState()
         let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 35, height: 50), target: targetFrame)
@@ -798,12 +799,7 @@ internal class IconsStyleKit: NSObject {
         fillColor7.setFill()
         bezier139Path.fill()
         
-        
-        
-        
-        
         context.restoreGState()
-        
         context.restoreGState()
         
     }
@@ -823,6 +819,20 @@ internal class IconsStyleKit: NSObject {
 
         return Cache.imageOfLetter!
     }
+    
+    @objc open dynamic class var imageOfLetterButton: UIImage {
+        if Cache.imageOfLetterButton != nil {
+            return Cache.imageOfLetterButton!
+        }
+        
+        UIGraphicsBeginImageContextWithOptions(CGSize(width: 50, height: 35), false, 0)
+        IconsStyleKit.drawLetter(color: IconsStyleKit.Cache.buttonStrokeColor)
+        
+        Cache.imageOfLetterButton = UIGraphicsGetImageFromCurrentImageContext()!
+        UIGraphicsEndImageContext()
+        
+        return Cache.imageOfLetterButton!
+    }
 
     @objc open dynamic class var imageOfLetterBG: UIImage {
         if Cache.imageOfLetterBG != nil {
@@ -865,6 +875,21 @@ internal class IconsStyleKit: NSObject {
 
         return Cache.imageOfPostcard!
     }
+    
+    @objc open dynamic class var imageOfPostcardButton: UIImage {
+        if Cache.imageOfPostcardButton != nil {
+            return Cache.imageOfPostcardButton!
+        }
+        
+        UIGraphicsBeginImageContextWithOptions(CGSize(width: 49, height: 34), false, 0)
+        IconsStyleKit.drawPostcard(color: Cache.buttonStrokeColor)
+        
+        Cache.imageOfPostcardButton = UIGraphicsGetImageFromCurrentImageContext()!
+        UIGraphicsEndImageContext()
+        
+        return Cache.imageOfPostcardButton!
+    }
+
 
     @objc open dynamic class var imageOfPostcardBG: UIImage {
         if Cache.imageOfPostcardBG != nil {
@@ -908,6 +933,20 @@ internal class IconsStyleKit: NSObject {
         return Cache.imageOfPadlockSecure!
     }
     
+    @objc dynamic public class var imageOfPadlockSecureButton: UIImage {
+        if Cache.imageOfPadlockSecureButton != nil {
+            return Cache.imageOfPadlockSecureButton!
+        }
+        
+        UIGraphicsBeginImageContextWithOptions(CGSize(width: height, height: width), false, 0)
+        IconsStyleKit.drawPadlockSecure(color: Cache.buttonStrokeColor, fillBackground: false)
+        
+        Cache.imageOfPadlockSecureButton = UIGraphicsGetImageFromCurrentImageContext()!
+        UIGraphicsEndImageContext()
+        
+        return Cache.imageOfPadlockSecureButton!
+    }
+    
     @objc dynamic public class var imageOfPadlockSecureBG: UIImage {
         if Cache.imageOfPadlockSecureBG != nil {
             return Cache.imageOfPadlockSecureBG!
@@ -936,6 +975,20 @@ internal class IconsStyleKit: NSObject {
         return Cache.imageOfPadlockInsecure!
     }
     
+    @objc dynamic public class var imageOfPadlockInsecureButton: UIImage {
+        if Cache.imageOfPadlockInsecureButton != nil {
+            return Cache.imageOfPadlockInsecureButton!
+        }
+        
+        UIGraphicsBeginImageContextWithOptions(CGSize(width: height, height: width), false, 0)
+        IconsStyleKit.drawPadlockInsecure(color: Cache.buttonStrokeColor ,fillBackground: false)
+        
+        Cache.imageOfPadlockInsecureButton = UIGraphicsGetImageFromCurrentImageContext()!
+        UIGraphicsEndImageContext()
+        
+        return Cache.imageOfPadlockInsecureButton!
+    }
+    
     @objc dynamic public class var imageOfPadlockInsecureBG: UIImage {
         if Cache.imageOfPadlockInsecureBG != nil {
             return Cache.imageOfPadlockInsecureBG!
diff --git a/enzevalos_iphone/Theme.swift b/enzevalos_iphone/Theme.swift
index ed06dfd185ca210efe28ae38358574e58df43b77..21dc7bf5b4b9f22cf36ea86a481d44c724575338 100644
--- a/enzevalos_iphone/Theme.swift
+++ b/enzevalos_iphone/Theme.swift
@@ -24,6 +24,7 @@ let SelectedThemeKey = "security_indicator"
 let defaultColor = ThemeManager.defaultColor
 
 enum Theme: Int {
+    
     /*
      Our themes: 
      No security indicators -> no different colors, symbols
@@ -43,7 +44,7 @@ enum Theme: Int {
         default:
             // orange
 //            return UIColor(red: 247/255, green: 185/255, blue: 0/255, alpha: 1.0)
-            return UIColor(red: 255 / 255, green: 204 / 255, blue: 0 / 255, alpha: 1.0)
+            return ThemeManager.orange
 
         }
     }
@@ -57,7 +58,7 @@ enum Theme: Int {
         default:
             // green
 //            return UIColor(red: 115/255, green: 229/255, blue: 105/255, alpha: 1.0)
-            return UIColor(red: 76 / 255, green: 217 / 255, blue: 100 / 255, alpha: 1.0)
+            return ThemeManager.green
         }
     }
 
@@ -69,20 +70,20 @@ enum Theme: Int {
             return defaultColor
         default:
             // green
-            return UIColor(red: 76 / 255, green: 217 / 255, blue: 100 / 255, alpha: 1.0)
+            return ThemeManager.green
         }
     }
 
     var troubleMessageColor: UIColor {
         switch self {
         case .no_security_indicator:
-            return defaultColor
+            return ThemeManager.defaultColor
         case .weak_security_indicator:
-            return defaultColor
+            return ThemeManager.defaultColor
         default:
             // red
 //            return UIColor(red: 255/255, green: 99/255, blue: 99/255, alpha: 1.0)
-            return UIColor(red: 255 / 255, green: 59 / 255, blue: 48 / 255, alpha: 1.0)
+            return ThemeManager.red
 
         }
     }
@@ -90,11 +91,16 @@ enum Theme: Int {
 
 
 struct ThemeManager {
+    static let orange =  UIColor(red: 255 / 255, green: 204 / 255, blue: 0 / 255, alpha: 1.0)
+    static let green = UIColor(red: 76 / 255, green: 217 / 255, blue: 100 / 255, alpha: 1.0)
+    static let red = UIColor(red: 255 / 255, green: 59 / 255, blue: 48 / 255, alpha: 1.0)
+    static let defaultColor: UIColor = UIColor(red: 249 / 255, green: 249 / 255, blue: 249 / 255, alpha: 1.0)
+
     static func currentTheme() -> Theme {
         if let storedTheme = (UserDefaults.standard.value(forKey: SelectedThemeKey) as? Int) {
             return Theme(rawValue: storedTheme)!
         } else {
-            return .very_strong_security_indicator
+            return .no_security_indicator
         }
     }
 
@@ -115,7 +121,7 @@ struct ThemeManager {
     }
 
     static func animation() -> Bool {
-        return currentTheme() == .very_strong_security_indicator
+        return true
     }
 
     static func applyTheme(_ theme: Theme) {
@@ -123,6 +129,5 @@ struct ThemeManager {
         UserDefaults.standard.synchronize()
     }
 
-    static var defaultColor: UIColor = UIColor(red: 249 / 255, green: 249 / 255, blue: 249 / 255, alpha: 1.0)
 }
 
diff --git a/enzevalos_iphone/UserData.swift b/enzevalos_iphone/UserData.swift
index 6da46ead183e45a06630b986651ef34510b83e17..c86d1ea2074b99c3bafc6fb3dbfc5d36c02b528d 100644
--- a/enzevalos_iphone/UserData.swift
+++ b/enzevalos_iphone/UserData.swift
@@ -190,7 +190,16 @@ struct UserManager {
         let value = UserDefaults.standard.value(forKey: "\(attribute.rawValue)")
         if value != nil {
             return value as AnyObject?
-        } else {
+        }
+        if attribute == .accountname {
+            // fix bug when accountname is missing
+            if let value = loadUserValue(_:.userAddr) {
+                storeUserValue(value, attribute: .accountname)
+                return value
+            }
+            return attribute.defaultValue
+        }
+        else {
             _ = storeUserValue(attribute.defaultValue, attribute: attribute)
             return attribute.defaultValue
         }
diff --git a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone 6.xcdatamodel/contents b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone 6.xcdatamodel/contents
index 712ada75e6494aa3c3aa143334503e0eb83c007e..cc6a8a2d1abaac670e7735144bd5c5683e4f5a07 100644
--- a/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone 6.xcdatamodel/contents	
+++ b/enzevalos_iphone/enzevalos_iphone.xcdatamodeld/enzevalos_iphone 6.xcdatamodel/contents	
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14135" systemVersion="17G4015" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
+<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="17G6030" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
     <entity name="Account" representedClassName="Account" syncable="YES" codeGenerationType="class">
         <attribute name="archiveFolderPath" attributeType="String" syncable="YES"/>
         <attribute name="displayName" attributeType="String" syncable="YES"/>
@@ -42,19 +42,21 @@
         <attribute name="icon" optional="YES" attributeType="String" syncable="YES"/>
         <attribute name="lastUpdate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
         <attribute name="maxID" optional="YES" attributeType="Decimal" defaultValueString="1" syncable="YES"/>
+        <attribute name="minUID" optional="YES" attributeType="Decimal" defaultValueString="0.0" syncable="YES"/>
         <attribute name="path" attributeType="String" syncable="YES"/>
         <attribute name="pseudonym" attributeType="String" syncable="YES"/>
         <attribute name="uidvalidity" optional="YES" attributeType="Decimal" defaultValueString="0.0" syncable="YES"/>
         <relationship name="keyRecords" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="KeyRecord" inverseName="folder" inverseEntity="KeyRecord" syncable="YES"/>
-        <relationship name="mails" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="folder" inverseEntity="PersistentMail" syncable="YES"/>
+        <relationship name="mails" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PersistentMail" inverseName="folder" inverseEntity="PersistentMail" syncable="YES"/>
         <relationship name="parent" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Folder" inverseName="subfolder" inverseEntity="Folder" syncable="YES"/>
         <relationship name="subfolder" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Folder" inverseName="parent" inverseEntity="Folder" syncable="YES"/>
     </entity>
     <entity name="KeyRecord" representedClassName="KeyRecord" syncable="YES">
+        <attribute name="newestDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
         <relationship name="contact" maxCount="1" deletionRule="Nullify" destinationEntity="EnzevalosContact" inverseName="keyrecords" inverseEntity="EnzevalosContact" syncable="YES"/>
         <relationship name="folder" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Folder" inverseName="keyRecords" inverseEntity="Folder" syncable="YES"/>
         <relationship name="key" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PersistentKey" inverseName="record" inverseEntity="PersistentKey" syncable="YES"/>
-        <relationship name="persistentMails" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="PersistentMail" inverseName="record" inverseEntity="PersistentMail" syncable="YES"/>
+        <relationship name="persistentMails" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PersistentMail" inverseName="record" inverseEntity="PersistentMail" syncable="YES"/>
     </entity>
     <entity name="Mail_Address" representedClassName="Mail_Address" syncable="YES">
         <attribute name="address" attributeType="String" defaultValueString="&quot;&quot;" syncable="YES"/>
@@ -153,14 +155,15 @@
         <relationship name="imap" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Account" inverseName="imap" inverseEntity="Account" syncable="YES"/>
         <relationship name="smtp" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Account" inverseName="smtp" inverseEntity="Account" syncable="YES"/>
     </entity>
+    <fetchRequest name="allKeyRecords" entity="KeyRecord" predicateString="NOT (FALSEPREDICATE)" returnDistinctResults="YES"/>
     <fetchRequest name="getFolder" entity="Folder" predicateString="name == &quot;$folder&quot;"/>
     <fetchRequest name="getMailAddress" entity="Mail_Address" predicateString="address == &quot;$adr&quot;"/>
     <elements>
         <element name="Account" positionX="-315" positionY="-36" width="128" height="255"/>
         <element name="Attachment" positionX="-315" positionY="-36" width="128" height="210"/>
         <element name="EnzevalosContact" positionX="-209" positionY="198" width="128" height="120"/>
-        <element name="Folder" positionX="-297" positionY="-18" width="128" height="225"/>
-        <element name="KeyRecord" positionX="-315" positionY="-36" width="128" height="105"/>
+        <element name="Folder" positionX="-297" positionY="-18" width="128" height="240"/>
+        <element name="KeyRecord" positionX="-315" positionY="-36" width="128" height="30"/>
         <element name="Mail_Address" positionX="-297" positionY="-18" width="128" height="210"/>
         <element name="PersistentKey" positionX="-315" positionY="-36" width="128" height="390"/>
         <element name="PersistentMail" positionX="-416" positionY="-189" width="128" height="30"/>
diff --git a/enzevalos_iphone/mail/IncomingMail.swift b/enzevalos_iphone/mail/IncomingMail.swift
index e24abaddbc26f241f3c17c9ec292679a225192d0..20b654120b2d291c37811826937e094dfd2c7bd3 100644
--- a/enzevalos_iphone/mail/IncomingMail.swift
+++ b/enzevalos_iphone/mail/IncomingMail.swift
@@ -242,7 +242,7 @@ class IncomingMail {
     }
     
     func store(keyRecord: KeyRecord?) -> PersistentMail? {
-        let sk = secretKeys.first //TODO FIX
+        let sk = secretKeys.first //TODO FIX: may import more secret keys?
         let mail = DataHandler.handler.createMail(uID, sender: from, receivers: rec, cc: cc, time: date, received: true, subject: subject, body: body, readableAttachments: readableAttachments, flags: flags, record: keyRecord, autocrypt: autocrypt, decryptedData: cryptoObj, folderPath: folderPath, secretKey: sk, references: references, mailagent: userAgent, messageID: msgID, encryptedBody: encryptedBody, storeEncrypted: storeEncrypted)
         if let m = mail {
             let pgp = SwiftPGP()
diff --git a/enzevalos_iphone/study parameters/SecurityIndicator.swift b/enzevalos_iphone/study parameters/SecurityIndicator.swift
index 8c1489cf932d7396d21cdf80daa73b48d5066440..aa25e283f21ca62d96a1a17dd09dd25abd470766 100644
--- a/enzevalos_iphone/study parameters/SecurityIndicator.swift	
+++ b/enzevalos_iphone/study parameters/SecurityIndicator.swift	
@@ -62,9 +62,12 @@ enum SecurityIndicator: Int, StudyParameterProtocol {
     
     
     
-    func imageOfSecureIndicator(background: Bool = false, open: Bool = false) -> UIImage {
+    func imageOfSecureIndicator(background: Bool = false, open: Bool = false, button: Bool = false) -> UIImage {
         switch self {
         case .letter:
+            if button {
+                return IconsStyleKit.imageOfLetterButton
+            }
             if open {
                 return IconsStyleKit.imageOfLetterOpen
             }
@@ -73,6 +76,9 @@ enum SecurityIndicator: Int, StudyParameterProtocol {
             }
             return IconsStyleKit.imageOfLetter
         case .padlock:
+            if button {
+                return IconsStyleKit.imageOfPadlockSecureButton
+            }
             if background {
                 return IconsStyleKit.imageOfPadlockSecureBG
             }
@@ -90,14 +96,20 @@ enum SecurityIndicator: Int, StudyParameterProtocol {
         }
     }
     
-    func imageOfInsecureIndicator(background: Bool = false) -> UIImage {
+    func imageOfInsecureIndicator(background: Bool = false, button: Bool = false) -> UIImage {
         switch self {
         case .letter:
+            if button {
+                return IconsStyleKit.imageOfPostcardButton
+            }
             if background {
                 return IconsStyleKit.imageOfPostcardBG
             }
             return IconsStyleKit.imageOfPostcard
         case .padlock:
+            if button {
+                return IconsStyleKit.imageOfPadlockInsecureButton
+            }
             if background {
                 return IconsStyleKit.imageOfPadlockInsecureBG
             }
diff --git a/enzevalos_iphone/study parameters/StudyParameterProtocol.swift b/enzevalos_iphone/study parameters/StudyParameterProtocol.swift
index 72e54d75544a67795c62268a8ac9a806999713a5..6f449b6dca61f44137bf1ec4c7fc08038e6af9e3 100644
--- a/enzevalos_iphone/study parameters/StudyParameterProtocol.swift	
+++ b/enzevalos_iphone/study parameters/StudyParameterProtocol.swift	
@@ -36,7 +36,6 @@ extension StudyParameterProtocol {
             try keychain.remove(self.keyName)
         }
         catch {
-            print(error)
             return false
         }
 
diff --git a/enzevalos_iphoneTests/CoreDataTests.swift b/enzevalos_iphoneTests/CoreDataTests.swift
index 68ba9eb36e4b6c65aaea3c1263cc8a07364fa71c..2c2dbae7ebe7c4c3b3ca63fdce0e95b26bed918b 100644
--- a/enzevalos_iphoneTests/CoreDataTests.swift
+++ b/enzevalos_iphoneTests/CoreDataTests.swift
@@ -312,4 +312,24 @@ class CoraDataTests: XCTestCase {
 
         return mail
     }
+    
+    func testKeysPerAddress() {
+        let adrKey = "key@example.com"
+        let adrNoKey = "noKey@example.com"
+        let adrNoKey2 = "noKey2@example.com"
+        var mailAdrKey = datahandler.getMailAddress(adrKey, temporary: false)
+        let mailAdrNoKey = datahandler.getMailAddress(adrNoKey, temporary: false)
+        _ = datahandler.getMailAddress(adrNoKey2, temporary: false)
+        XCTAssertFalse(mailAdrKey.hasKey)
+        XCTAssertFalse(mailAdrNoKey.hasKey)
+        XCTAssertEqual(datahandler.getAddresses().count, 3)
+        _ = datahandler.newPublicKey(keyID: "000", cryptoType: .PGP, adr: adrKey, autocrypt: false)
+        _ = datahandler.newPublicKey(keyID: "001", cryptoType: .PGP, adr: adrKey, autocrypt: false)
+        mailAdrKey = datahandler.getMailAddress(adrKey, temporary: false)
+        XCTAssertTrue(mailAdrKey.hasKey)
+        let withKeys = datahandler.findMailAddress(withKey: true).count
+        let noKeys = datahandler.findMailAddress(withKey: false).count
+        XCTAssertEqual(withKeys, 1, "Adresses with key: \(withKeys)")
+        XCTAssertEqual(noKeys, 2, "Adresses without key: \(noKeys)")        
+    }
 }
diff --git a/enzevalos_iphoneUITests/OnboardingTest.swift b/enzevalos_iphoneUITests/OnboardingTest.swift
new file mode 100644
index 0000000000000000000000000000000000000000..887258d652e70cf2d8237d2d4e9473ef129eb8d8
--- /dev/null
+++ b/enzevalos_iphoneUITests/OnboardingTest.swift
@@ -0,0 +1,40 @@
+//
+//  OnboardingTest.swift
+//  enzevalos_iphoneUITests
+//
+//  Created by Oliver Wiese on 21.05.19.
+//  Copyright © 2019 fu-berlin. All rights reserved.
+//
+
+import XCTest
+
+class OnboardingTest: XCTestCase {
+    var app: XCUIApplication!
+
+    override func setUp() {
+        // Put setup code here. This method is called before the invocation of each test method in the class.
+        app = XCUIApplication()
+        app.launch()
+        
+        // In UI tests it is usually best to stop immediately when a failure occurs.
+        continueAfterFailure = false
+
+        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
+    }
+
+    override func tearDown() {
+        // Put teardown code here. This method is called after the invocation of each test method in the class.
+    }
+ 
+
+    func testLogging() {
+        // Use recording to get started writing UI tests.
+        // Use XCTAssert and related functions to verify your tests produce the correct results.
+        app.otherElements.containing(.pageIndicator, identifier:"page 1 of 5").children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.swipeLeft()
+
+        app.otherElements.containing(.pageIndicator, identifier:"page 2 of 5").children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.swipeLeft()
+        app/*@START_MENU_TOKEN@*/.staticTexts["OnboardSubTextAccessibilityIdentifier"]/*[[".staticTexts[\"You, the sender and both mail providers know the content of the mail but who sent the mail?\\nSender addresses can be freely chosen. A fraud can impersonate a person when using a known mail address as sender address.\"]",".staticTexts[\"OnboardSubTextAccessibilityIdentifier\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.swipeLeft()
+        app.otherElements["OnboardInputViewAccessibilityIdentifier"].swipeLeft()
+    }
+
+}