merge refactor IOS-1520
authorAlejandro Gelos <alejandro@pep-project.org>
Mon, 20 May 2019 16:30:04 +0200
branchIOS-1520
changeset 2857460f9b05bb57
parent 2337 6651d9aa0068
parent 2750 d060f9643f3c
merge refactor
MessageModel/MessageModel/Interface/VerificationService.swift
MessageModel/MessageModel/Modules/Log/MMLog.swift
MessageModel/MessageModel/NetworkService/IMAP/EmailConnectInfo.swift
MessageModel/MessageModel/NetworkService/Network/ConnectInfo/EmailConnectInfo+Extension.swift
MessageModel/MessageModel/NetworkService/Network/Service/AccountVerificationService/AccountVerificationService.swift
MessageModel/MessageModel/NetworkService/Network/Service/MessageSyncService/VerificationServiceProtocol.swift
MessageModel/MessageModel/NetworkService/NetworkServiceConfig.swift
MessageModel/MessageModel/NetworkService/Service/VerificationByLogin/VerifiableAccountProtocol.swift
MessageModel/MessageModel/NetworkService/Util/MimeTypeUtil.swift
MessageModel/MessageModel/NetworkService/Util/NSSecureCoding+Extension.swift
MessageModel/MessageModel/Util/Log.swift
     1.1 --- a/.hgignore	Fri May 03 12:19:46 2019 +0200
     1.2 +++ b/.hgignore	Mon May 20 16:30:04 2019 +0200
     1.3 @@ -1,3 +1,4 @@
     1.4 +syntax: regexp
     1.5  \.DS_Store
     1.6  project.xcworkspace/.*
     1.7  xcuserdata/.*
     2.1 --- a/MessageModel/MessageModel.xcodeproj/project.pbxproj	Fri May 03 12:19:46 2019 +0200
     2.2 +++ b/MessageModel/MessageModel.xcodeproj/project.pbxproj	Mon May 20 16:30:04 2019 +0200
     2.3 @@ -29,19 +29,25 @@
     2.4  		1587D137204570BB002C2157 /* MessageModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1587D135204570BA002C2157 /* MessageModel.xcdatamodeld */; };
     2.5  		1587D167204DA3C3002C2157 /* KeyChain+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1587D166204DA3C2002C2157 /* KeyChain+Extensions.swift */; };
     2.6  		15CCE2C52225BCE5004A8306 /* CoreDataEntityAttributeNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15CCE2C42225BCE5004A8306 /* CoreDataEntityAttributeNames.swift */; };
     2.7 -		15CCE2FB22297228004A8306 /* MMLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15CCE2FA22297228004A8306 /* MMLog.swift */; };
     2.8 +		15CCE2FB22297228004A8306 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15CCE2FA22297228004A8306 /* Log.swift */; };
     2.9  		15CCE30022297464004A8306 /* LogTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15CCE2FF22297464004A8306 /* LogTest.swift */; };
    2.10  		15EA8E011FA8A45E00D4084A /* CdIdentity+PredicateFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15EA8E001FA8A45E00D4084A /* CdIdentity+PredicateFactory.swift */; };
    2.11  		15ECD7061F5430C1002889B8 /* Message+TestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15ECD7051F5430C1002889B8 /* Message+TestUtils.swift */; };
    2.12  		15F0F7B42136F68A002BE853 /* CdFolder+PredicateFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15F0F7B32136F68A002BE853 /* CdFolder+PredicateFactory.swift */; };
    2.13  		15F82A06200649390084F9EA /* ServerCredentialsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15F82A05200649390084F9EA /* ServerCredentialsTest.swift */; };
    2.14  		15F835261F386DE400FCE887 /* CdServer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15F835251F386DE400FCE887 /* CdServer+Extensions.swift */; };
    2.15 +		370DB3D12281795000BC929A /* ContentTypeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370DB3D02281795000BC929A /* ContentTypeUtils.swift */; };
    2.16  		372904792252492D00B3B801 /* MessageModelService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372904782252492D00B3B801 /* MessageModelService.swift */; };
    2.17  		374A8AE6224E2D16001914D5 /* RelationshipKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 374A8AE5224E2D16001914D5 /* RelationshipKeyPath.swift */; };
    2.18  		37BC7AEE222014D20047267A /* MessageQueryResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BC7AED222014D20047267A /* MessageQueryResults.swift */; };
    2.19  		37BC7AF32220187E0047267A /* MessageQueryResultsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BC7AF22220187E0047267A /* MessageQueryResultsTest.swift */; };
    2.20  		37BC7AFB22283E2D0047267A /* MessageModelObjectUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BC7AFA22283E2D0047267A /* MessageModelObjectUtils.swift */; };
    2.21  		37BC7B00222D23460047267A /* MessageModelObjectUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BC7AFF222D23460047267A /* MessageModelObjectUtilsTest.swift */; };
    2.22 +		37E61A602271B513000DF876 /* Account+Fetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E61A5F2271B513000DF876 /* Account+Fetching.swift */; };
    2.23 +		37E61A622271BCE8000DF876 /* Account+FetchingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E61A612271BCE8000DF876 /* Account+FetchingTest.swift */; };
    2.24 +		37EA033B228C1B6D0069FD91 /* CdAccount+Trusted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37EA033A228C1B6D0069FD91 /* CdAccount+Trusted.swift */; };
    2.25 +		37FED96E228328ED004C7804 /* MimeTypeUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FED96D228328ED004C7804 /* MimeTypeUtilsTest.swift */; };
    2.26 +		37FED9712283354B004C7804 /* jsonMimeType.txt in Resources */ = {isa = PBXBuildFile; fileRef = 37FED9702283354A004C7804 /* jsonMimeType.txt */; };
    2.27  		430A2EF01E82758100878837 /* CdImapFields+TestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430A2EEF1E82758100878837 /* CdImapFields+TestHelper.swift */; };
    2.28  		430A2EF21E829C4600878837 /* AddressBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430A2EF11E829C4600878837 /* AddressBook.swift */; };
    2.29  		430A2EF41E829C9100878837 /* AddressBookTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430A2EF31E829C9100878837 /* AddressBookTests.swift */; };
    2.30 @@ -50,6 +56,7 @@
    2.31  		43123FB9225369660038D72C /* CdMessage+NonOptionalConvenienceAccessors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43123FB8225369660038D72C /* CdMessage+NonOptionalConvenienceAccessors.swift */; };
    2.32  		43123FBD225374030038D72C /* CdFolder+IMAP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43123FBC225374030038D72C /* CdFolder+IMAP.swift */; };
    2.33  		43123FC2225388FB0038D72C /* CdMessage+IMAP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43123FC1225388FB0038D72C /* CdMessage+IMAP.swift */; };
    2.34 +		4312BE7C22841C5A0002129D /* SecretTestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4312BE7B22841C5A0002129D /* SecretTestData.swift */; };
    2.35  		433019E21E0181EB00788B89 /* MessageModelConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433019E11E0181EB00788B89 /* MessageModelConfig.swift */; };
    2.36  		433C51D51E6828AE00272E19 /* MessageID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433C51D41E6828AE00272E19 /* MessageID.swift */; };
    2.37  		433E743A225B76E000B84CD9 /* CdServer+NonOptionalConvenienceAccessors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433E7439225B76E000B84CD9 /* CdServer+NonOptionalConvenienceAccessors.swift */; };
    2.38 @@ -71,10 +78,10 @@
    2.39  		435F5134221FFF3A006EB11F /* CdFolder+Pantomime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435F5133221FFF3A006EB11F /* CdFolder+Pantomime.swift */; };
    2.40  		435F5139222005D6006EB11F /* MatchUidToMsnOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435F5138222005D6006EB11F /* MatchUidToMsnOperation.swift */; };
    2.41  		435F513B22200638006EB11F /* StorePrefetchedMailOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435F513A22200638006EB11F /* StorePrefetchedMailOperation.swift */; };
    2.42 -		435F514022200F83006EB11F /* NetworkServiceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435F513F22200F83006EB11F /* NetworkServiceConfig.swift */; };
    2.43  		435F514C222017E8006EB11F /* CdAttachment+Pantomime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435F514B222017E8006EB11F /* CdAttachment+Pantomime.swift */; };
    2.44  		435F518122204731006EB11F /* PEPObjCAdapterFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 435F518022204731006EB11F /* PEPObjCAdapterFramework.framework */; };
    2.45  		4360AA1A22281B7100E62E5A /* PEPSession+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4360AA1922281B7100E62E5A /* PEPSession+Extensions.swift */; };
    2.46 +		436981B52282F8D40006FA2D /* PEPObjCAdapterFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 436981B42282F8D40006FA2D /* PEPObjCAdapterFramework.framework */; };
    2.47  		436991CD2237B584006B517E /* PantomimeFramework.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 43EA489C221E95E3006E8F83 /* PantomimeFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
    2.48  		43753CC2222D247D002EE98B /* CdMessage+pEp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43753CC1222D247D002EE98B /* CdMessage+pEp.swift */; };
    2.49  		43753CC7222D2855002EE98B /* CWIMAPMessage+pEp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43753CC6222D2855002EE98B /* CWIMAPMessage+pEp.swift */; };
    2.50 @@ -83,7 +90,13 @@
    2.51  		43753CEE222D3A3E002EE98B /* CdAttachment+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43753CED222D3A3E002EE98B /* CdAttachment+Extension.swift */; };
    2.52  		437AA507224507A200B5C7A4 /* CdFolder+NonOptionalConvenienceAccessors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437AA506224507A200B5C7A4 /* CdFolder+NonOptionalConvenienceAccessors.swift */; };
    2.53  		4380DA511EF281740016904E /* NSManagedObjectContext+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4380DA501EF281730016904E /* NSManagedObjectContext+Extension.swift */; };
    2.54 -		43A6011822648F420099B45C /* VerifiableAccountProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A6011722648F420099B45C /* VerifiableAccountProtocol.swift */; };
    2.55 +		439B16A222802A8700201DE5 /* VerifiableAccountProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439B16A122802A8700201DE5 /* VerifiableAccountProtocol.swift */; };
    2.56 +		439B16AA22802B6B00201DE5 /* VerifiableAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439B16A522802B6B00201DE5 /* VerifiableAccount.swift */; };
    2.57 +		439B16AB22802B6B00201DE5 /* VerifiableAccountSMTP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439B16A622802B6B00201DE5 /* VerifiableAccountSMTP.swift */; };
    2.58 +		439B16AC22802B6B00201DE5 /* BasicConnectInfo+VerifiableAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439B16A722802B6B00201DE5 /* BasicConnectInfo+VerifiableAccount.swift */; };
    2.59 +		439B16AD22802B6B00201DE5 /* VerifiableAccountIMAP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439B16A822802B6B00201DE5 /* VerifiableAccountIMAP.swift */; };
    2.60 +		439B16B222802D3800201DE5 /* VerifiableAccountTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439B16B122802D3800201DE5 /* VerifiableAccountTest.swift */; };
    2.61 +		439B16B622802F0600201DE5 /* TestDataBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439B16B422802F0600201DE5 /* TestDataBase.swift */; };
    2.62  		43A6E05C1E57725C005BEE69 /* CdKey+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A6E05B1E57725C005BEE69 /* CdKey+Extension.swift */; };
    2.63  		43AABD4120EF5D2E00FBD5D0 /* CdMessage+Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AABD4020EF5D2E00FBD5D0 /* CdMessage+Util.swift */; };
    2.64  		43AB6A0F2248D228008E40CC /* CdAccount+NonOptionalConvenienceAccessors.swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AB6A0E2248D228008E40CC /* CdAccount+NonOptionalConvenienceAccessors.swift.swift */; };
    2.65 @@ -95,19 +108,14 @@
    2.66  		43AE48F41EEFECD400B92BB6 /* NSMergeConflict+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AE48F31EEFECD400B92BB6 /* NSMergeConflict+Extension.swift */; };
    2.67  		43AE48F81EF01EE900B92BB6 /* NSManagedObject+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AE48F71EF01EE900B92BB6 /* NSManagedObject+Extension.swift */; };
    2.68  		43B1A39C22366D9700C387DE /* AppAuth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43B1A39B22366D9700C387DE /* AppAuth.framework */; };
    2.69 -		43B1B105221EB6C900DB26AB /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B1B104221EB6C900DB26AB /* Log.swift */; };
    2.70  		43B1B10C221ED15000DB26AB /* PersistentImapFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B1B10B221ED15000DB26AB /* PersistentImapFolder.swift */; };
    2.71  		43C123C5223A73E100F6A9B2 /* CheckOutgoingMessagesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123C0223A73E100F6A9B2 /* CheckOutgoingMessagesOperation.swift */; };
    2.72  		43C123C6223A73E100F6A9B2 /* DeleteFoldersOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123C1223A73E100F6A9B2 /* DeleteFoldersOperation.swift */; };
    2.73  		43C123C7223A73E100F6A9B2 /* FetchOlderImapMessagesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123C2223A73E100F6A9B2 /* FetchOlderImapMessagesOperation.swift */; };
    2.74  		43C123C8223A73E100F6A9B2 /* FolderInfoOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123C3223A73E100F6A9B2 /* FolderInfoOperation.swift */; };
    2.75  		43C123C9223A73E100F6A9B2 /* DeleteFolderOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123C4223A73E100F6A9B2 /* DeleteFolderOperation.swift */; };
    2.76 -		43C123E6223A7FCF00F6A9B2 /* EmailConnectInfo+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123D5223A7FCF00F6A9B2 /* EmailConnectInfo+Extension.swift */; };
    2.77 -		43C123E7223A7FCF00F6A9B2 /* VerificationServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123D9223A7FCF00F6A9B2 /* VerificationServiceProtocol.swift */; };
    2.78 -		43C123E8223A7FCF00F6A9B2 /* VerificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123DA223A7FCF00F6A9B2 /* VerificationService.swift */; };
    2.79  		43C123E9223A7FCF00F6A9B2 /* QualifyServerIsLocalServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123DB223A7FCF00F6A9B2 /* QualifyServerIsLocalServiceProtocol.swift */; };
    2.80  		43C123EA223A7FCF00F6A9B2 /* QualifyServerIsLocalOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123DC223A7FCF00F6A9B2 /* QualifyServerIsLocalOperation.swift */; };
    2.81 -		43C123EB223A7FCF00F6A9B2 /* AccountVerificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123DE223A7FCF00F6A9B2 /* AccountVerificationService.swift */; };
    2.82  		43C123EC223A7FCF00F6A9B2 /* AccountVerificationServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123DF223A7FCF00F6A9B2 /* AccountVerificationServiceProtocol.swift */; };
    2.83  		43C123ED223A7FCF00F6A9B2 /* QualifyServerIsLocalService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123E0223A7FCF00F6A9B2 /* QualifyServerIsLocalService.swift */; };
    2.84  		43C123EE223A7FCF00F6A9B2 /* FolderSyncServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C123E2223A7FCF00F6A9B2 /* FolderSyncServiceProtocol.swift */; };
    2.85 @@ -165,9 +173,8 @@
    2.86  		43EA486A221E9518006E8F83 /* Notification+CWServiceClientNotificationParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA480F221E9518006E8F83 /* Notification+CWServiceClientNotificationParsing.swift */; };
    2.87  		43EA486B221E9518006E8F83 /* CdMessage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4810221E9518006E8F83 /* CdMessage+Extension.swift */; };
    2.88  		43EA486C221E9518006E8F83 /* ServiceUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4811221E9518006E8F83 /* ServiceUtil.swift */; };
    2.89 -		43EA486D221E9518006E8F83 /* NSSecureCoding+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4812221E9518006E8F83 /* NSSecureCoding+Extension.swift */; };
    2.90  		43EA486E221E9518006E8F83 /* Message+IMAP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4813221E9518006E8F83 /* Message+IMAP.swift */; };
    2.91 -		43EA486F221E9518006E8F83 /* MimeTypeUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4814221E9518006E8F83 /* MimeTypeUtil.swift */; };
    2.92 +		43EA486F221E9518006E8F83 /* MimeTypeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4814221E9518006E8F83 /* MimeTypeUtils.swift */; };
    2.93  		43EA4870221E9518006E8F83 /* OAuth2AccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4816221E9518006E8F83 /* OAuth2AccessToken.swift */; };
    2.94  		43EA4871221E9518006E8F83 /* OAuth2AccessTokenProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4817221E9518006E8F83 /* OAuth2AccessTokenProtocol.swift */; };
    2.95  		43EA4872221E9518006E8F83 /* ReplicationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EA4818221E9518006E8F83 /* ReplicationService.swift */; };
    2.96 @@ -305,7 +312,7 @@
    2.97  		1587D136204570BA002C2157 /* pEpForiOS.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = pEpForiOS.xcdatamodel; sourceTree = "<group>"; };
    2.98  		1587D166204DA3C2002C2157 /* KeyChain+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyChain+Extensions.swift"; sourceTree = "<group>"; };
    2.99  		15CCE2C42225BCE5004A8306 /* CoreDataEntityAttributeNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataEntityAttributeNames.swift; sourceTree = "<group>"; };
   2.100 -		15CCE2FA22297228004A8306 /* MMLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MMLog.swift; sourceTree = "<group>"; };
   2.101 +		15CCE2FA22297228004A8306 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
   2.102  		15CCE2FF22297464004A8306 /* LogTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogTest.swift; sourceTree = "<group>"; };
   2.103  		15EA8E001FA8A45E00D4084A /* CdIdentity+PredicateFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdIdentity+PredicateFactory.swift"; sourceTree = "<group>"; };
   2.104  		15ECD7051F5430C1002889B8 /* Message+TestUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Message+TestUtils.swift"; sourceTree = "<group>"; };
   2.105 @@ -313,12 +320,18 @@
   2.106  		15F0F7B32136F68A002BE853 /* CdFolder+PredicateFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdFolder+PredicateFactory.swift"; sourceTree = "<group>"; };
   2.107  		15F82A05200649390084F9EA /* ServerCredentialsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerCredentialsTest.swift; sourceTree = "<group>"; };
   2.108  		15F835251F386DE400FCE887 /* CdServer+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CdServer+Extensions.swift"; sourceTree = "<group>"; };
   2.109 +		370DB3D02281795000BC929A /* ContentTypeUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentTypeUtils.swift; sourceTree = "<group>"; };
   2.110  		372904782252492D00B3B801 /* MessageModelService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageModelService.swift; sourceTree = "<group>"; };
   2.111  		374A8AE5224E2D16001914D5 /* RelationshipKeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelationshipKeyPath.swift; sourceTree = "<group>"; };
   2.112  		37BC7AED222014D20047267A /* MessageQueryResults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageQueryResults.swift; sourceTree = "<group>"; };
   2.113  		37BC7AF22220187E0047267A /* MessageQueryResultsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageQueryResultsTest.swift; sourceTree = "<group>"; };
   2.114  		37BC7AFA22283E2D0047267A /* MessageModelObjectUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageModelObjectUtils.swift; sourceTree = "<group>"; };
   2.115  		37BC7AFF222D23460047267A /* MessageModelObjectUtilsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageModelObjectUtilsTest.swift; sourceTree = "<group>"; };
   2.116 +		37E61A5F2271B513000DF876 /* Account+Fetching.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Account+Fetching.swift"; sourceTree = "<group>"; };
   2.117 +		37E61A612271BCE8000DF876 /* Account+FetchingTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+FetchingTest.swift"; sourceTree = "<group>"; };
   2.118 +		37EA033A228C1B6D0069FD91 /* CdAccount+Trusted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdAccount+Trusted.swift"; sourceTree = "<group>"; };
   2.119 +		37FED96D228328ED004C7804 /* MimeTypeUtilsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MimeTypeUtilsTest.swift; sourceTree = "<group>"; };
   2.120 +		37FED9702283354A004C7804 /* jsonMimeType.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = jsonMimeType.txt; sourceTree = "<group>"; };
   2.121  		430A2EEF1E82758100878837 /* CdImapFields+TestHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CdImapFields+TestHelper.swift"; sourceTree = "<group>"; };
   2.122  		430A2EF11E829C4600878837 /* AddressBook.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressBook.swift; sourceTree = "<group>"; };
   2.123  		430A2EF31E829C9100878837 /* AddressBookTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressBookTests.swift; sourceTree = "<group>"; };
   2.124 @@ -327,6 +340,7 @@
   2.125  		43123FB8225369660038D72C /* CdMessage+NonOptionalConvenienceAccessors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdMessage+NonOptionalConvenienceAccessors.swift"; sourceTree = "<group>"; };
   2.126  		43123FBC225374030038D72C /* CdFolder+IMAP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdFolder+IMAP.swift"; sourceTree = "<group>"; };
   2.127  		43123FC1225388FB0038D72C /* CdMessage+IMAP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdMessage+IMAP.swift"; sourceTree = "<group>"; };
   2.128 +		4312BE7B22841C5A0002129D /* SecretTestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SecretTestData.swift; path = ../../../../pEp_for_iOS_intern/SecretTestData.swift; sourceTree = "<group>"; };
   2.129  		433019E11E0181EB00788B89 /* MessageModelConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageModelConfig.swift; sourceTree = "<group>"; };
   2.130  		433C51D41E6828AE00272E19 /* MessageID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageID.swift; sourceTree = "<group>"; };
   2.131  		433E7439225B76E000B84CD9 /* CdServer+NonOptionalConvenienceAccessors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdServer+NonOptionalConvenienceAccessors.swift"; sourceTree = "<group>"; };
   2.132 @@ -348,10 +362,10 @@
   2.133  		435F5133221FFF3A006EB11F /* CdFolder+Pantomime.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CdFolder+Pantomime.swift"; sourceTree = "<group>"; };
   2.134  		435F5138222005D6006EB11F /* MatchUidToMsnOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatchUidToMsnOperation.swift; sourceTree = "<group>"; };
   2.135  		435F513A22200638006EB11F /* StorePrefetchedMailOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorePrefetchedMailOperation.swift; sourceTree = "<group>"; };
   2.136 -		435F513F22200F83006EB11F /* NetworkServiceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkServiceConfig.swift; sourceTree = "<group>"; };
   2.137  		435F514B222017E8006EB11F /* CdAttachment+Pantomime.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CdAttachment+Pantomime.swift"; sourceTree = "<group>"; };
   2.138  		435F518022204731006EB11F /* PEPObjCAdapterFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PEPObjCAdapterFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
   2.139  		4360AA1922281B7100E62E5A /* PEPSession+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PEPSession+Extensions.swift"; sourceTree = "<group>"; };
   2.140 +		436981B42282F8D40006FA2D /* PEPObjCAdapterFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PEPObjCAdapterFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
   2.141  		43753CC1222D247D002EE98B /* CdMessage+pEp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdMessage+pEp.swift"; sourceTree = "<group>"; };
   2.142  		43753CC6222D2855002EE98B /* CWIMAPMessage+pEp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CWIMAPMessage+pEp.swift"; sourceTree = "<group>"; };
   2.143  		43753CDD222D2DA7002EE98B /* ContentDispositionType+Conversion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ContentDispositionType+Conversion.swift"; sourceTree = "<group>"; };
   2.144 @@ -359,7 +373,13 @@
   2.145  		43753CED222D3A3E002EE98B /* CdAttachment+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CdAttachment+Extension.swift"; sourceTree = "<group>"; };
   2.146  		437AA506224507A200B5C7A4 /* CdFolder+NonOptionalConvenienceAccessors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdFolder+NonOptionalConvenienceAccessors.swift"; sourceTree = "<group>"; };
   2.147  		4380DA501EF281730016904E /* NSManagedObjectContext+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Extension.swift"; sourceTree = "<group>"; };
   2.148 -		43A6011722648F420099B45C /* VerifiableAccountProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifiableAccountProtocol.swift; sourceTree = "<group>"; };
   2.149 +		439B16A122802A8700201DE5 /* VerifiableAccountProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifiableAccountProtocol.swift; sourceTree = "<group>"; };
   2.150 +		439B16A522802B6B00201DE5 /* VerifiableAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifiableAccount.swift; sourceTree = "<group>"; };
   2.151 +		439B16A622802B6B00201DE5 /* VerifiableAccountSMTP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifiableAccountSMTP.swift; sourceTree = "<group>"; };
   2.152 +		439B16A722802B6B00201DE5 /* BasicConnectInfo+VerifiableAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BasicConnectInfo+VerifiableAccount.swift"; sourceTree = "<group>"; };
   2.153 +		439B16A822802B6B00201DE5 /* VerifiableAccountIMAP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifiableAccountIMAP.swift; sourceTree = "<group>"; };
   2.154 +		439B16B122802D3800201DE5 /* VerifiableAccountTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifiableAccountTest.swift; sourceTree = "<group>"; };
   2.155 +		439B16B422802F0600201DE5 /* TestDataBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestDataBase.swift; sourceTree = "<group>"; };
   2.156  		43A6E05B1E57725C005BEE69 /* CdKey+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CdKey+Extension.swift"; sourceTree = "<group>"; };
   2.157  		43AABD4020EF5D2E00FBD5D0 /* CdMessage+Util.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdMessage+Util.swift"; sourceTree = "<group>"; };
   2.158  		43AB6A0E2248D228008E40CC /* CdAccount+NonOptionalConvenienceAccessors.swift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CdAccount+NonOptionalConvenienceAccessors.swift.swift"; sourceTree = "<group>"; };
   2.159 @@ -371,19 +391,14 @@
   2.160  		43AE48F31EEFECD400B92BB6 /* NSMergeConflict+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSMergeConflict+Extension.swift"; sourceTree = "<group>"; };
   2.161  		43AE48F71EF01EE900B92BB6 /* NSManagedObject+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Extension.swift"; sourceTree = "<group>"; };
   2.162  		43B1A39B22366D9700C387DE /* AppAuth.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AppAuth.framework; sourceTree = BUILT_PRODUCTS_DIR; };
   2.163 -		43B1B104221EB6C900DB26AB /* Log.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
   2.164  		43B1B10B221ED15000DB26AB /* PersistentImapFolder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersistentImapFolder.swift; sourceTree = "<group>"; };
   2.165  		43C123C0223A73E100F6A9B2 /* CheckOutgoingMessagesOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckOutgoingMessagesOperation.swift; sourceTree = "<group>"; };
   2.166  		43C123C1223A73E100F6A9B2 /* DeleteFoldersOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeleteFoldersOperation.swift; sourceTree = "<group>"; };
   2.167  		43C123C2223A73E100F6A9B2 /* FetchOlderImapMessagesOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchOlderImapMessagesOperation.swift; sourceTree = "<group>"; };
   2.168  		43C123C3223A73E100F6A9B2 /* FolderInfoOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolderInfoOperation.swift; sourceTree = "<group>"; };
   2.169  		43C123C4223A73E100F6A9B2 /* DeleteFolderOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeleteFolderOperation.swift; sourceTree = "<group>"; };
   2.170 -		43C123D5223A7FCF00F6A9B2 /* EmailConnectInfo+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EmailConnectInfo+Extension.swift"; sourceTree = "<group>"; };
   2.171 -		43C123D9223A7FCF00F6A9B2 /* VerificationServiceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerificationServiceProtocol.swift; sourceTree = "<group>"; };
   2.172 -		43C123DA223A7FCF00F6A9B2 /* VerificationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerificationService.swift; sourceTree = "<group>"; };
   2.173  		43C123DB223A7FCF00F6A9B2 /* QualifyServerIsLocalServiceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QualifyServerIsLocalServiceProtocol.swift; sourceTree = "<group>"; };
   2.174  		43C123DC223A7FCF00F6A9B2 /* QualifyServerIsLocalOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QualifyServerIsLocalOperation.swift; sourceTree = "<group>"; };
   2.175 -		43C123DE223A7FCF00F6A9B2 /* AccountVerificationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountVerificationService.swift; sourceTree = "<group>"; };
   2.176  		43C123DF223A7FCF00F6A9B2 /* AccountVerificationServiceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountVerificationServiceProtocol.swift; sourceTree = "<group>"; };
   2.177  		43C123E0223A7FCF00F6A9B2 /* QualifyServerIsLocalService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QualifyServerIsLocalService.swift; sourceTree = "<group>"; };
   2.178  		43C123E2223A7FCF00F6A9B2 /* FolderSyncServiceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolderSyncServiceProtocol.swift; sourceTree = "<group>"; };
   2.179 @@ -444,9 +459,8 @@
   2.180  		43EA480F221E9518006E8F83 /* Notification+CWServiceClientNotificationParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Notification+CWServiceClientNotificationParsing.swift"; sourceTree = "<group>"; };
   2.181  		43EA4810221E9518006E8F83 /* CdMessage+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CdMessage+Extension.swift"; sourceTree = "<group>"; };
   2.182  		43EA4811221E9518006E8F83 /* ServiceUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceUtil.swift; sourceTree = "<group>"; };
   2.183 -		43EA4812221E9518006E8F83 /* NSSecureCoding+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSSecureCoding+Extension.swift"; sourceTree = "<group>"; };
   2.184  		43EA4813221E9518006E8F83 /* Message+IMAP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Message+IMAP.swift"; sourceTree = "<group>"; };
   2.185 -		43EA4814221E9518006E8F83 /* MimeTypeUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MimeTypeUtil.swift; sourceTree = "<group>"; };
   2.186 +		43EA4814221E9518006E8F83 /* MimeTypeUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MimeTypeUtils.swift; sourceTree = "<group>"; };
   2.187  		43EA4816221E9518006E8F83 /* OAuth2AccessToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OAuth2AccessToken.swift; sourceTree = "<group>"; };
   2.188  		43EA4817221E9518006E8F83 /* OAuth2AccessTokenProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OAuth2AccessTokenProtocol.swift; sourceTree = "<group>"; };
   2.189  		43EA4818221E9518006E8F83 /* ReplicationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplicationService.swift; sourceTree = "<group>"; };
   2.190 @@ -549,6 +563,7 @@
   2.191  			isa = PBXFrameworksBuildPhase;
   2.192  			buildActionMask = 2147483647;
   2.193  			files = (
   2.194 +				436981B52282F8D40006FA2D /* PEPObjCAdapterFramework.framework in Frameworks */,
   2.195  				49E6CE3B1E72F70B004EE2AD /* MessageModel.framework in Frameworks */,
   2.196  			);
   2.197  			runOnlyForDeploymentPostprocessing = 0;
   2.198 @@ -562,9 +577,9 @@
   2.199  				37904542223BFDCB006DAB3B /* MessageQueryResults */,
   2.200  				15175EFA222538B200C91DB8 /* MessageModel */,
   2.201  				15175E4D221D59F400C91DB8 /* MessageModelObjects */,
   2.202 +				439B16A022802A8700201DE5 /* VerifiableAccount */,
   2.203  				372904782252492D00B3B801 /* MessageModelService.swift */,
   2.204  				43C123E4223A7FCF00F6A9B2 /* FetchOlderImapMessagesService.swift */,
   2.205 -				43C123DA223A7FCF00F6A9B2 /* VerificationService.swift */,
   2.206  			);
   2.207  			path = Interface;
   2.208  			sourceTree = "<group>";
   2.209 @@ -590,6 +605,7 @@
   2.210  		15175E4F221D5B3200C91DB8 /* Interface */ = {
   2.211  			isa = PBXGroup;
   2.212  			children = (
   2.213 +				37E61A5F2271B513000DF876 /* Account+Fetching.swift */,
   2.214  				433C51D41E6828AE00272E19 /* MessageID.swift */,
   2.215  				434DC0D61DAE7407007C98B8 /* Account.swift */,
   2.216  				43CB609E1DA4EBB60015281E /* Folder.swift */,
   2.217 @@ -631,6 +647,7 @@
   2.218  				8B8D228E1DBA0A26000BDE79 /* CdServerCredentials.swift */,
   2.219  				43F484451E8130A80028BC1A /* CdImapFields+Extension.swift */,
   2.220  				43F484431E8130180028BC1A /* CdImapFlags+Extension.swift */,
   2.221 +				37EA033A228C1B6D0069FD91 /* CdAccount+Trusted.swift */,
   2.222  			);
   2.223  			path = NSManagedObjectExtensions;
   2.224  			sourceTree = "<group>";
   2.225 @@ -742,7 +759,7 @@
   2.226  		15CCE2F9222971FE004A8306 /* Log */ = {
   2.227  			isa = PBXGroup;
   2.228  			children = (
   2.229 -				15CCE2FA22297228004A8306 /* MMLog.swift */,
   2.230 +				15CCE2FA22297228004A8306 /* Log.swift */,
   2.231  			);
   2.232  			path = Log;
   2.233  			sourceTree = "<group>";
   2.234 @@ -768,6 +785,7 @@
   2.235  		37BC7AF0222018480047267A /* MessageModelObjects */ = {
   2.236  			isa = PBXGroup;
   2.237  			children = (
   2.238 +				37E61A612271BCE8000DF876 /* Account+FetchingTest.swift */,
   2.239  			);
   2.240  			path = MessageModelObjects;
   2.241  			sourceTree = "<group>";
   2.242 @@ -808,6 +826,33 @@
   2.243  			path = Accessors;
   2.244  			sourceTree = "<group>";
   2.245  		};
   2.246 +		439B16A022802A8700201DE5 /* VerifiableAccount */ = {
   2.247 +			isa = PBXGroup;
   2.248 +			children = (
   2.249 +				439B16A122802A8700201DE5 /* VerifiableAccountProtocol.swift */,
   2.250 +				439B16A522802B6B00201DE5 /* VerifiableAccount.swift */,
   2.251 +			);
   2.252 +			path = VerifiableAccount;
   2.253 +			sourceTree = "<group>";
   2.254 +		};
   2.255 +		439B16A322802B6B00201DE5 /* VerifiableAccount */ = {
   2.256 +			isa = PBXGroup;
   2.257 +			children = (
   2.258 +				439B16A722802B6B00201DE5 /* BasicConnectInfo+VerifiableAccount.swift */,
   2.259 +				439B16A622802B6B00201DE5 /* VerifiableAccountSMTP.swift */,
   2.260 +				439B16A822802B6B00201DE5 /* VerifiableAccountIMAP.swift */,
   2.261 +			);
   2.262 +			path = VerifiableAccount;
   2.263 +			sourceTree = "<group>";
   2.264 +		};
   2.265 +		439B16B022802D3800201DE5 /* Service */ = {
   2.266 +			isa = PBXGroup;
   2.267 +			children = (
   2.268 +				439B16B122802D3800201DE5 /* VerifiableAccountTest.swift */,
   2.269 +			);
   2.270 +			path = Service;
   2.271 +			sourceTree = "<group>";
   2.272 +		};
   2.273  		43AB6A192248F381008E40CC /* ModelCache */ = {
   2.274  			isa = PBXGroup;
   2.275  			children = (
   2.276 @@ -824,24 +869,14 @@
   2.277  		43C123D3223A7FCF00F6A9B2 /* Network */ = {
   2.278  			isa = PBXGroup;
   2.279  			children = (
   2.280 -				43C123D4223A7FCF00F6A9B2 /* ConnectInfo */,
   2.281  				43C123D7223A7FCF00F6A9B2 /* Service */,
   2.282  			);
   2.283  			path = Network;
   2.284  			sourceTree = "<group>";
   2.285  		};
   2.286 -		43C123D4223A7FCF00F6A9B2 /* ConnectInfo */ = {
   2.287 -			isa = PBXGroup;
   2.288 -			children = (
   2.289 -				43C123D5223A7FCF00F6A9B2 /* EmailConnectInfo+Extension.swift */,
   2.290 -			);
   2.291 -			path = ConnectInfo;
   2.292 -			sourceTree = "<group>";
   2.293 -		};
   2.294  		43C123D7223A7FCF00F6A9B2 /* Service */ = {
   2.295  			isa = PBXGroup;
   2.296  			children = (
   2.297 -				43C123D8223A7FCF00F6A9B2 /* MessageSyncService */,
   2.298  				43C123DB223A7FCF00F6A9B2 /* QualifyServerIsLocalServiceProtocol.swift */,
   2.299  				43C123DC223A7FCF00F6A9B2 /* QualifyServerIsLocalOperation.swift */,
   2.300  				43C123DD223A7FCF00F6A9B2 /* AccountVerificationService */,
   2.301 @@ -852,18 +887,9 @@
   2.302  			path = Service;
   2.303  			sourceTree = "<group>";
   2.304  		};
   2.305 -		43C123D8223A7FCF00F6A9B2 /* MessageSyncService */ = {
   2.306 -			isa = PBXGroup;
   2.307 -			children = (
   2.308 -				43C123D9223A7FCF00F6A9B2 /* VerificationServiceProtocol.swift */,
   2.309 -			);
   2.310 -			path = MessageSyncService;
   2.311 -			sourceTree = "<group>";
   2.312 -		};
   2.313  		43C123DD223A7FCF00F6A9B2 /* AccountVerificationService */ = {
   2.314  			isa = PBXGroup;
   2.315  			children = (
   2.316 -				43C123DE223A7FCF00F6A9B2 /* AccountVerificationService.swift */,
   2.317  				43C123DF223A7FCF00F6A9B2 /* AccountVerificationServiceProtocol.swift */,
   2.318  			);
   2.319  			path = AccountVerificationService;
   2.320 @@ -921,6 +947,7 @@
   2.321  				15175EBF221D74E400C91DB8 /* Modules */,
   2.322  				490FF8111E79726300BC15F9 /* CoreData */,
   2.323  				153E4E4B1F5038E00021CBD8 /* Model */,
   2.324 +				439B16B022802D3800201DE5 /* Service */,
   2.325  				490FF8061E795B6C00BC15F9 /* Util */,
   2.326  				B72BD8B31E698B8C00A65FF2 /* FolderWithFilterModuleTest.swift */,
   2.327  				43CB60901DA4EB4E0015281E /* MessageModelTests.swift */,
   2.328 @@ -936,7 +963,6 @@
   2.329  			children = (
   2.330  				15865A852031990200F7A4B5 /* PredicateFacories */,
   2.331  				4352D07E1DAB7B4C00F2E218 /* MessageModelLogging.swift */,
   2.332 -				43B1B104221EB6C900DB26AB /* Log.swift */,
   2.333  				490FF7FD1E795B1500BC15F9 /* Int16+ImapFlagBits.swift */,
   2.334  				433019E11E0181EB00788B89 /* MessageModelConfig.swift */,
   2.335  				B7FE66491DDF1E73008A53BE /* MessageModelData.swift */,
   2.336 @@ -954,20 +980,11 @@
   2.337  			path = Util;
   2.338  			sourceTree = "<group>";
   2.339  		};
   2.340 -		43D47E5E2260C9DC00E97C5B /* VerificationByLogin */ = {
   2.341 -			isa = PBXGroup;
   2.342 -			children = (
   2.343 -				43A6011722648F420099B45C /* VerifiableAccountProtocol.swift */,
   2.344 -			);
   2.345 -			path = VerificationByLogin;
   2.346 -			sourceTree = "<group>";
   2.347 -		};
   2.348  		43EA47E6221E9518006E8F83 /* NetworkService */ = {
   2.349  			isa = PBXGroup;
   2.350  			children = (
   2.351  				43EA4818221E9518006E8F83 /* ReplicationService.swift */,
   2.352  				43EA4830221E9518006E8F83 /* NetworkServiceWorker.swift */,
   2.353 -				435F513F22200F83006EB11F /* NetworkServiceConfig.swift */,
   2.354  				437AA5052245078A00B5C7A4 /* Accessors */,
   2.355  				43EA47E7221E9518006E8F83 /* IMAP */,
   2.356  				43EA47ED221E9518006E8F83 /* Util */,
   2.357 @@ -980,6 +997,7 @@
   2.358  				43EA4838221E9518006E8F83 /* Service */,
   2.359  				43EA483C221E9518006E8F83 /* Error */,
   2.360  				43C123D3223A7FCF00F6A9B2 /* Network */,
   2.361 +				439B16A322802B6B00201DE5 /* VerifiableAccount */,
   2.362  			);
   2.363  			path = NetworkService;
   2.364  			sourceTree = "<group>";
   2.365 @@ -990,7 +1008,6 @@
   2.366  				43EA47E8221E9518006E8F83 /* ImapService.swift */,
   2.367  				43EA47E9221E9518006E8F83 /* DefaultImapSyncDelegate.swift */,
   2.368  				43EA47EA221E9518006E8F83 /* ImapConnectionDataCache.swift */,
   2.369 -				43EA47EB221E9518006E8F83 /* EmailConnectInfo.swift */,
   2.370  				43EA47EC221E9518006E8F83 /* ImapFolderBuilder.swift */,
   2.371  				43D47E522260B73300E97C5B /* EmailConnectInfo+BasicConnectInfo.swift */,
   2.372  			);
   2.373 @@ -1013,6 +1030,7 @@
   2.374  				43EA47F1221E9518006E8F83 /* Folder+Imap.swift */,
   2.375  				43EA47F3221E9518006E8F83 /* Message+FakeMessage.swift */,
   2.376  				43EA47F9221E9518006E8F83 /* ConnectInfo.swift */,
   2.377 +				43EA47EB221E9518006E8F83 /* EmailConnectInfo.swift */,
   2.378  				43D47E502260AEBF00E97C5B /* BasicConnectInfo.swift */,
   2.379  				43EA47FB221E9518006E8F83 /* CdMessage+Pantomime.swift */,
   2.380  				43EA47FC221E9518006E8F83 /* Attachment+Extension.swift */,
   2.381 @@ -1031,10 +1049,10 @@
   2.382  				43EA480F221E9518006E8F83 /* Notification+CWServiceClientNotificationParsing.swift */,
   2.383  				43EA4810221E9518006E8F83 /* CdMessage+Extension.swift */,
   2.384  				43EA4811221E9518006E8F83 /* ServiceUtil.swift */,
   2.385 -				43EA4812221E9518006E8F83 /* NSSecureCoding+Extension.swift */,
   2.386  				43EA4813221E9518006E8F83 /* Message+IMAP.swift */,
   2.387  				43123FC1225388FB0038D72C /* CdMessage+IMAP.swift */,
   2.388 -				43EA4814221E9518006E8F83 /* MimeTypeUtil.swift */,
   2.389 +				43EA4814221E9518006E8F83 /* MimeTypeUtils.swift */,
   2.390 +				370DB3D02281795000BC929A /* ContentTypeUtils.swift */,
   2.391  				435C0CBF222939A10025C6B5 /* PEPRating+Extension.swift */,
   2.392  				435C0CCC222942DE0025C6B5 /* Identity+pEp.swift */,
   2.393  				435C0CCE2229433D0025C6B5 /* CdIdentity+pEp.swift */,
   2.394 @@ -1048,6 +1066,7 @@
   2.395  				43E3A24F224E4280004CAC84 /* CdHeaderField+Clone.swift */,
   2.396  				43E3A254224E473B004CAC84 /* CdMessage+Fake.swift */,
   2.397  				43123FBC225374030038D72C /* CdFolder+IMAP.swift */,
   2.398 +				37FED9702283354A004C7804 /* jsonMimeType.txt */,
   2.399  				43EA47F4221E9518006E8F83 /* VirtualMailbox */,
   2.400  			);
   2.401  			path = Util;
   2.402 @@ -1139,7 +1158,6 @@
   2.403  		43EA4838221E9518006E8F83 /* Service */ = {
   2.404  			isa = PBXGroup;
   2.405  			children = (
   2.406 -				43D47E5E2260C9DC00E97C5B /* VerificationByLogin */,
   2.407  				43EA4839221E9518006E8F83 /* SmtpService.swift */,
   2.408  				43EA483A221E9518006E8F83 /* FetchNumberOfNewMailsService.swift */,
   2.409  				43EA483B221E9518006E8F83 /* EmailService.swift */,
   2.410 @@ -1179,8 +1197,11 @@
   2.411  		490FF8061E795B6C00BC15F9 /* Util */ = {
   2.412  			isa = PBXGroup;
   2.413  			children = (
   2.414 +				4312BE7B22841C5A0002129D /* SecretTestData.swift */,
   2.415 +				439B16B422802F0600201DE5 /* TestDataBase.swift */,
   2.416  				490FF8071E795B6C00BC15F9 /* Int16+FlagBitsTest.swift */,
   2.417  				37BC7AFF222D23460047267A /* MessageModelObjectUtilsTest.swift */,
   2.418 +				37FED96D228328ED004C7804 /* MimeTypeUtilsTest.swift */,
   2.419  			);
   2.420  			path = Util;
   2.421  			sourceTree = "<group>";
   2.422 @@ -1241,6 +1262,7 @@
   2.423  		B7DB7FA322147000003968DA /* Frameworks */ = {
   2.424  			isa = PBXGroup;
   2.425  			children = (
   2.426 +				436981B42282F8D40006FA2D /* PEPObjCAdapterFramework.framework */,
   2.427  				43B1A39B22366D9700C387DE /* AppAuth.framework */,
   2.428  				435F518022204731006EB11F /* PEPObjCAdapterFramework.framework */,
   2.429  				43EA489C221E95E3006E8F83 /* PantomimeFramework.framework */,
   2.430 @@ -1353,6 +1375,7 @@
   2.431  			isa = PBXResourcesBuildPhase;
   2.432  			buildActionMask = 2147483647;
   2.433  			files = (
   2.434 +				37FED9712283354B004C7804 /* jsonMimeType.txt in Resources */,
   2.435  			);
   2.436  			runOnlyForDeploymentPostprocessing = 0;
   2.437  		};
   2.438 @@ -1455,7 +1478,7 @@
   2.439  				B718EF341F867015000CFB71 /* SearchFilter.swift in Sources */,
   2.440  				1587D137204570BB002C2157 /* MessageModel.xcdatamodeld in Sources */,
   2.441  				43EA486C221E9518006E8F83 /* ServiceUtil.swift in Sources */,
   2.442 -				43EA486F221E9518006E8F83 /* MimeTypeUtil.swift in Sources */,
   2.443 +				43EA486F221E9518006E8F83 /* MimeTypeUtils.swift in Sources */,
   2.444  				4352D07F1DAB7B4C00F2E218 /* MessageModelLogging.swift in Sources */,
   2.445  				437AA507224507A200B5C7A4 /* CdFolder+NonOptionalConvenienceAccessors.swift in Sources */,
   2.446  				43EA4861221E9518006E8F83 /* Folder+pEp.swift in Sources */,
   2.447 @@ -1469,9 +1492,9 @@
   2.448  				43EA4859221E9518006E8F83 /* CdFolder+Extension.swift in Sources */,
   2.449  				15865A8420318E2D00F7A4B5 /* CdMessage+PredicateFactory.swift in Sources */,
   2.450  				43D47A50225C751500E97C5B /* ServerInfoCache.swift in Sources */,
   2.451 +				439B16AC22802B6B00201DE5 /* BasicConnectInfo+VerifiableAccount.swift in Sources */,
   2.452  				43EA4853221E9518006E8F83 /* ProviderSpecificInformationProtocol.swift in Sources */,
   2.453  				15CCE2C52225BCE5004A8306 /* CoreDataEntityAttributeNames.swift in Sources */,
   2.454 -				43EA486D221E9518006E8F83 /* NSSecureCoding+Extension.swift in Sources */,
   2.455  				43C123C9223A73E100F6A9B2 /* DeleteFolderOperation.swift in Sources */,
   2.456  				43F609802248BCBD0008B900 /* CdFolder+VirtualMailbox.swift in Sources */,
   2.457  				430A2EF21E829C4600878837 /* AddressBook.swift in Sources */,
   2.458 @@ -1490,7 +1513,6 @@
   2.459  				43EA485F221E9518006E8F83 /* KickOffMySelfProtocol.swift in Sources */,
   2.460  				43EA488F221E9518006E8F83 /* FetchNumberOfNewMailsService.swift in Sources */,
   2.461  				43B1B10C221ED15000DB26AB /* PersistentImapFolder.swift in Sources */,
   2.462 -				43B1B105221EB6C900DB26AB /* Log.swift in Sources */,
   2.463  				43EA4850221E9518006E8F83 /* Folder+VirtualMailbox.swift in Sources */,
   2.464  				43EA4869221E9518006E8F83 /* CdMessagePredicateFactory+Extension.swift in Sources */,
   2.465  				43C123F0223A7FCF00F6A9B2 /* FetchOlderImapMessagesService.swift in Sources */,
   2.466 @@ -1504,6 +1526,7 @@
   2.467  				433E743F225B77BA00B84CD9 /* CdServerCredentials+NonOptionalConvenienceAccessors.swift.swift in Sources */,
   2.468  				B7789CCA22243DC800AB08F4 /* MessageQueryResultsFilter.swift in Sources */,
   2.469  				43E3A24C224E3AE7004CAC84 /* CdKey+Clone.swift in Sources */,
   2.470 +				37EA033B228C1B6D0069FD91 /* CdAccount+Trusted.swift in Sources */,
   2.471  				43EA4852221E9518006E8F83 /* GmailSpecificInformation.swift in Sources */,
   2.472  				435C0CCD222942DE0025C6B5 /* Identity+pEp.swift in Sources */,
   2.473  				43D47A4E225C729900E97C5B /* AccountInfoCache.swift in Sources */,
   2.474 @@ -1511,6 +1534,7 @@
   2.475  				8BA887661DBF4076003B58F1 /* MessageReference.swift in Sources */,
   2.476  				15175ECA221DB6DC00C91DB8 /* QueryResultsControllerState.swift in Sources */,
   2.477  				43EA487B221E9518006E8F83 /* FetchMessagesOperation.swift in Sources */,
   2.478 +				439B16A222802A8700201DE5 /* VerifiableAccountProtocol.swift in Sources */,
   2.479  				15F0F7B42136F68A002BE853 /* CdFolder+PredicateFactory.swift in Sources */,
   2.480  				43753CDE222D2DA7002EE98B /* ContentDispositionType+Conversion.swift in Sources */,
   2.481  				15175ECE221DC39300C91DB8 /* QueryResultsControllerDelegate.swift in Sources */,
   2.482 @@ -1528,14 +1552,16 @@
   2.483  				8BE460911DB7B5FC008D63C6 /* Record.swift in Sources */,
   2.484  				43EA4884221E9518006E8F83 /* SyncFoldersFromServerOperation.swift in Sources */,
   2.485  				43EA4883221E9518006E8F83 /* LoginImapOperation.swift in Sources */,
   2.486 +				37E61A602271B513000DF876 /* Account+Fetching.swift in Sources */,
   2.487  				43C123EE223A7FCF00F6A9B2 /* FolderSyncServiceProtocol.swift in Sources */,
   2.488 +				439B16AA22802B6B00201DE5 /* VerifiableAccount.swift in Sources */,
   2.489  				43EA4870221E9518006E8F83 /* OAuth2AccessToken.swift in Sources */,
   2.490  				434DC0E01DAE78BE007C98B8 /* Attachment.swift in Sources */,
   2.491 -				43A6011822648F420099B45C /* VerifiableAccountProtocol.swift in Sources */,
   2.492  				43C123C7223A73E100F6A9B2 /* FetchOlderImapMessagesOperation.swift in Sources */,
   2.493  				43E3A255224E473B004CAC84 /* CdMessage+Fake.swift in Sources */,
   2.494  				43EA487C221E9518006E8F83 /* FixAttachmentsOperation.swift in Sources */,
   2.495  				43E3A246224E2DBA004CAC84 /* CdImapFlags+Clone.swift in Sources */,
   2.496 +				370DB3D12281795000BC929A /* ContentTypeUtils.swift in Sources */,
   2.497  				43C12408223A9DEA00F6A9B2 /* CdAccount+pEp.swift in Sources */,
   2.498  				43EA488C221E9518006E8F83 /* UnifiedFilter.swift in Sources */,
   2.499  				43E3A24A224E35D3004CAC84 /* CdAttachment+Clone.swift in Sources */,
   2.500 @@ -1548,11 +1574,9 @@
   2.501  				8BE460901DB7B5FC008D63C6 /* Query.swift in Sources */,
   2.502  				002C0C88213FDC0B003EAA4B /* UnreadOrFlaggedFilter.swift in Sources */,
   2.503  				43EA4871221E9518006E8F83 /* OAuth2AccessTokenProtocol.swift in Sources */,
   2.504 -				435F514022200F83006EB11F /* NetworkServiceConfig.swift in Sources */,
   2.505  				43C123C8223A73E100F6A9B2 /* FolderInfoOperation.swift in Sources */,
   2.506  				43EA4895221E9518006E8F83 /* PantomimeError.swift in Sources */,
   2.507  				B7FE664A1DDF1E73008A53BE /* MessageModelData.swift in Sources */,
   2.508 -				43C123EB223A7FCF00F6A9B2 /* AccountVerificationService.swift in Sources */,
   2.509  				43AB6A152248EDC5008E40CC /* FolderInfoCache.swift in Sources */,
   2.510  				8BE460871DB7B4A8008D63C6 /* CdMessageReference.swift in Sources */,
   2.511  				43EA486A221E9518006E8F83 /* Notification+CWServiceClientNotificationParsing.swift in Sources */,
   2.512 @@ -1572,7 +1596,6 @@
   2.513  				37BC7AFB22283E2D0047267A /* MessageModelObjectUtils.swift in Sources */,
   2.514  				152F09672126D27E001BCF20 /* CdServer+PredicateFactory.swift in Sources */,
   2.515  				8BE460851DB7B480008D63C6 /* CdMessageKeyword.swift in Sources */,
   2.516 -				43C123E6223A7FCF00F6A9B2 /* EmailConnectInfo+Extension.swift in Sources */,
   2.517  				8B21DF6E1DB8F00300E1576F /* MessageModelProtocols.swift in Sources */,
   2.518  				43EA4889221E9518006E8F83 /* NetworkServiceWorker.swift in Sources */,
   2.519  				43AE48F41EEFECD400B92BB6 /* NSMergeConflict+Extension.swift in Sources */,
   2.520 @@ -1588,7 +1611,6 @@
   2.521  				43EA4888221E9518006E8F83 /* SelfReferencingOperation.swift in Sources */,
   2.522  				435F5122221FF80F006EB11F /* SmtpSendError.swift in Sources */,
   2.523  				43EA4874221E9518006E8F83 /* AppendMailsOperation.swift in Sources */,
   2.524 -				43C123E8223A7FCF00F6A9B2 /* VerificationService.swift in Sources */,
   2.525  				434DC0E61DAE8BE7007C98B8 /* MutableOrderedSet.swift in Sources */,
   2.526  				15F835261F386DE400FCE887 /* CdServer+Extensions.swift in Sources */,
   2.527  				15175EFC222538D700C91DB8 /* MessageModelProtocol.swift in Sources */,
   2.528 @@ -1605,6 +1627,7 @@
   2.529  				43EA488E221E9518006E8F83 /* SmtpService.swift in Sources */,
   2.530  				43EA4882221E9518006E8F83 /* FetchNumberOfNewMailsOperation.swift in Sources */,
   2.531  				435F5120221FF750006EB11F /* PEPUtil.swift in Sources */,
   2.532 +				439B16AB22802B6B00201DE5 /* VerifiableAccountSMTP.swift in Sources */,
   2.533  				43EA4890221E9518006E8F83 /* EmailService.swift in Sources */,
   2.534  				B718EF381F867015000CFB71 /* AccountFilter.swift in Sources */,
   2.535  				43F484461E8130A80028BC1A /* CdImapFields+Extension.swift in Sources */,
   2.536 @@ -1621,7 +1644,6 @@
   2.537  				43EA486B221E9518006E8F83 /* CdMessage+Extension.swift in Sources */,
   2.538  				43D47A52225C767B00E97C5B /* ServerCredentialsInfoCache.swift in Sources */,
   2.539  				43EA4851221E9518006E8F83 /* PantomimeFolderAttribute+Extensions.swift in Sources */,
   2.540 -				43C123E7223A7FCF00F6A9B2 /* VerificationServiceProtocol.swift in Sources */,
   2.541  				43EA488D221E9518006E8F83 /* SharedObjects.swift in Sources */,
   2.542  				43123FB9225369660038D72C /* CdMessage+NonOptionalConvenienceAccessors.swift in Sources */,
   2.543  				43EA486E221E9518006E8F83 /* Message+IMAP.swift in Sources */,
   2.544 @@ -1649,9 +1671,10 @@
   2.545  				490FF7FE1E795B1500BC15F9 /* Int16+ImapFlagBits.swift in Sources */,
   2.546  				4352FA271DC7A1C20081161A /* KeyChain.swift in Sources */,
   2.547  				43C123EF223A7FCF00F6A9B2 /* FolderSyncService.swift in Sources */,
   2.548 -				15CCE2FB22297228004A8306 /* MMLog.swift in Sources */,
   2.549 +				15CCE2FB22297228004A8306 /* Log.swift in Sources */,
   2.550  				43EA4881221E9518006E8F83 /* BaseOperation.swift in Sources */,
   2.551  				43EA4891221E9518006E8F83 /* ReportingErrorContainer.swift in Sources */,
   2.552 +				439B16AD22802B6B00201DE5 /* VerifiableAccountIMAP.swift in Sources */,
   2.553  				43123FBD225374030038D72C /* CdFolder+IMAP.swift in Sources */,
   2.554  				435F513B22200638006EB11F /* StorePrefetchedMailOperation.swift in Sources */,
   2.555  				433019E21E0181EB00788B89 /* MessageModelConfig.swift in Sources */,
   2.556 @@ -1672,17 +1695,21 @@
   2.557  			isa = PBXSourcesBuildPhase;
   2.558  			buildActionMask = 2147483647;
   2.559  			files = (
   2.560 +				4312BE7C22841C5A0002129D /* SecretTestData.swift in Sources */,
   2.561  				15CCE30022297464004A8306 /* LogTest.swift in Sources */,
   2.562  				490FF8161E79942500BC15F9 /* CdImapFlags+TestHelper.swift in Sources */,
   2.563  				153E4E4D1F5038E00021CBD8 /* MessageTest.swift in Sources */,
   2.564  				43AE48E91EEFDD2100B92BB6 /* MergeConflictTests.swift in Sources */,
   2.565  				37BC7AF32220187E0047267A /* MessageQueryResultsTest.swift in Sources */,
   2.566 +				37E61A622271BCE8000DF876 /* Account+FetchingTest.swift in Sources */,
   2.567  				15F82A06200649390084F9EA /* ServerCredentialsTest.swift in Sources */,
   2.568  				37BC7B00222D23460047267A /* MessageModelObjectUtilsTest.swift in Sources */,
   2.569  				15175EE222240FB400C91DB8 /* QueryResultsChangeControllerTest.swift in Sources */,
   2.570 +				439B16B222802D3800201DE5 /* VerifiableAccountTest.swift in Sources */,
   2.571  				15175EE322240FB400C91DB8 /* QueryResultsControllerTest.swift in Sources */,
   2.572  				490FF8141E79726300BC15F9 /* CdImapFields+ImapFlagsTests.swift in Sources */,
   2.573  				490FF8031E795B3900BC15F9 /* MessageModelTestData.swift in Sources */,
   2.574 +				439B16B622802F0600201DE5 /* TestDataBase.swift in Sources */,
   2.575  				43CB60911DA4EB4E0015281E /* MessageModelTests.swift in Sources */,
   2.576  				490FF8051E795B3900BC15F9 /* TestUtil.swift in Sources */,
   2.577  				430A2EF01E82758100878837 /* CdImapFields+TestHelper.swift in Sources */,
   2.578 @@ -1691,6 +1718,7 @@
   2.579  				490FF8081E795B6C00BC15F9 /* Int16+FlagBitsTest.swift in Sources */,
   2.580  				153E4E4F1F5039C00021CBD8 /* PersistentStoreDrivenTestBase.swift in Sources */,
   2.581  				B7789CCF2225A5FE00AB08F4 /* MessageQueryResultsFilterTest.swift in Sources */,
   2.582 +				37FED96E228328ED004C7804 /* MimeTypeUtilsTest.swift in Sources */,
   2.583  				B72BD8B41E698B8C00A65FF2 /* FolderWithFilterModuleTest.swift in Sources */,
   2.584  				B7E02ABF2227F49600741157 /* MessageQueryResultsSearchTest.swift in Sources */,
   2.585  				430A2EF41E829C9100878837 /* AddressBookTests.swift in Sources */,
     3.1 --- a/MessageModel/MessageModel/Filter/FilterBase.swift	Fri May 03 12:19:46 2019 +0200
     3.2 +++ b/MessageModel/MessageModel/Filter/FilterBase.swift	Mon May 20 16:30:04 2019 +0200
     3.3 @@ -40,9 +40,7 @@
     3.4      }
     3.5  
     3.6      open func isEqual(filter: FilterBase) -> Bool {
     3.7 -        Log.shared.errorAndCrash(
     3.8 -            component: #function,
     3.9 -            errorString: "Override isEqual(filter)")
    3.10 +        Log.shared.errorAndCrash("Override isEqual(filter)")
    3.11          return false
    3.12      }
    3.13  
     4.1 --- a/MessageModel/MessageModel/Interface/FetchOlderImapMessagesService.swift	Fri May 03 12:19:46 2019 +0200
     4.2 +++ b/MessageModel/MessageModel/Interface/FetchOlderImapMessagesService.swift	Mon May 20 16:30:04 2019 +0200
     4.3 @@ -25,7 +25,7 @@
     4.4  
     4.5          guard let cdFolder = CdFolder.search(folder: folder),
     4.6              let cdAccount = cdFolder.account else {
     4.7 -                Logger.backendLogger.error(
     4.8 +                Log.shared.error(
     4.9                      "nconsistent DB state. CDFolder for Folder %{public}@ does not exist or its mandatory field \"account\" is not set.",
    4.10                      folder.name)
    4.11                  return
     5.1 --- a/MessageModel/MessageModel/Interface/MessageModel/MessageModel+PerformBlock.swift	Fri May 03 12:19:46 2019 +0200
     5.2 +++ b/MessageModel/MessageModel/Interface/MessageModel/MessageModel+PerformBlock.swift	Mon May 20 16:30:04 2019 +0200
     5.3 @@ -38,7 +38,7 @@
     5.4                  block()
     5.5              }
     5.6          } else {
     5.7 -            Log.shared.errorAndCrash(component: #function, errorString: "Unknown context used.")
     5.8 +            Log.shared.errorAndCrash("Unknown context used.")
     5.9          }
    5.10      }
    5.11  }
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Account+Fetching.swift	Mon May 20 16:30:04 2019 +0200
     6.3 @@ -0,0 +1,45 @@
     6.4 +//
     6.5 +//  Account+Fetching.swift
     6.6 +//  pEp
     6.7 +//
     6.8 +//  Created by Andreas Buff on 18.08.18.
     6.9 +//  Copyright © 2018 p≡p Security S.A. All rights reserved.
    6.10 +//
    6.11 +
    6.12 +import pEpIOSToolbox
    6.13 +
    6.14 +extension Account {
    6.15 +    public struct Fetch {
    6.16 +        /// Get all accounts that are allowed to be manually trusted.
    6.17 +        ///
    6.18 +        /// - Returns: Array of accounts allowed to be manually trusted
    6.19 +        static public func allAccountsAllowedToManuallyTrust() -> [Account] {
    6.20 +            let allowedPredicate = CdServer.PredicateFactory.isAllowedToManuallyTrust()
    6.21 +            let allowedCdServers = CdServer.all(predicate: allowedPredicate) as? [CdServer] ?? []
    6.22 +            var allowedAccounts = [Account]()
    6.23 +            for cdServer in allowedCdServers {
    6.24 +                guard let account = cdServer.account?.account() else {
    6.25 +                    Log.shared.errorAndCrash("No address")
    6.26 +                    continue
    6.27 +                }
    6.28 +                allowedAccounts.append(account)
    6.29 +            }
    6.30 +            return allowedAccounts
    6.31 +        }
    6.32 +
    6.33 +        /// Get an account from an address
    6.34 +        ///
    6.35 +        /// - Parameter address: address to search account
    6.36 +        /// - Returns: account with parameter address. Nil if none account with that address
    6.37 +        ///   was found
    6.38 +        static public func accountAllowedToManuallyTrust(fromAddress address: String) -> Account? {
    6.39 +            let accounts = allAccountsAllowedToManuallyTrust()
    6.40 +            for account in accounts {
    6.41 +                if account.user.address == address {
    6.42 +                    return account
    6.43 +                }
    6.44 +            }
    6.45 +            return nil
    6.46 +        }
    6.47 +    }
    6.48 +}
     7.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Account.swift	Fri May 03 12:19:46 2019 +0200
     7.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Account.swift	Mon May 20 16:30:04 2019 +0200
     7.3 @@ -85,10 +85,10 @@
     7.4              return nil
     7.5          }
     7.6          if serversForType.count > 1 {
     7.7 -            Log.shared.errorAndCrash(component: #function,
     7.8 -                                     errorString: "Invalid state. Account " +
     7.9 +            let error = "Invalid state. Account " +
    7.10                  "\(String(describing: user.address)) has more than one server of type " +
    7.11 -                "\(type.asString()) assigned. Assigned servers: \(servs)")
    7.12 +            "\(type.asString()) assigned. Assigned servers: \(servs)"
    7.13 +            Log.shared.errorAndCrash("%@", error)
    7.14          }
    7.15          return serversForType.first
    7.16      }
    7.17 @@ -127,15 +127,14 @@
    7.18              return
    7.19          }
    7.20          guard let cdServers = cdAccount.servers?.allObjects as? [CdServer] else {
    7.21 -            Log.shared.errorAndCrash(component: #function, errorString: "Invalid state.")
    7.22 +            Log.shared.errorAndCrash("Invalid state.")
    7.23              return
    7.24          }
    7.25          for server in servers {
    7.26              let type = server.serverType
    7.27              guard let cdServer = (cdServers.filter { $0.serverType == type }.first) else {
    7.28 -                Log.shared.errorAndCrash(component: #function,
    7.29 -                                         errorString:
    7.30 -                    "Invalid state: Server for type \(type) missing.")
    7.31 +                let error = "Invalid state: Server for type \(type) missing."
    7.32 +                Log.shared.errorAndCrash("%@", error)
    7.33                  return
    7.34              }
    7.35              server.credentials.key = cdServer.credentials?.key
     8.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/AddressBook.swift	Fri May 03 12:19:46 2019 +0200
     8.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/AddressBook.swift	Mon May 20 16:30:04 2019 +0200
     8.3 @@ -12,8 +12,6 @@
     8.4  import pEpIOSToolbox
     8.5  
     8.6  open class AddressBook {
     8.7 -    public let comp = "AddressBook"
     8.8 -
     8.9      let store = CNContactStore()
    8.10      private let splitRegex = try! NSRegularExpression(pattern: "(\\w+)", options: [])
    8.11  
    8.12 @@ -89,13 +87,13 @@
    8.13          do {
    8.14              try store.enumerateContacts(with: contactFetchRequest(), usingBlock: {[weak self] contact, stop in
    8.15                  guard let me = self else {
    8.16 -                    Log.shared.errorAndCrash(component: #function, errorString: "Lost myself")
    8.17 +                    Log.shared.errorAndCrash("Lost myself")
    8.18                      return
    8.19                  }
    8.20                  me.createIdentities(for: contact)
    8.21              })
    8.22          } catch {
    8.23 -            Log.shared.error(component: comp, error: error)
    8.24 +            Log.shared.error("%@", error.localizedDescription)
    8.25          }
    8.26  
    8.27          Record.saveAndWait()
     9.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Folder.swift	Fri May 03 12:19:46 2019 +0200
     9.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Folder.swift	Mon May 20 16:30:04 2019 +0200
     9.3 @@ -82,9 +82,7 @@
     9.4          let ft = cdFolder.folderType
     9.5  
     9.6          if cdFolder.name == nil {
     9.7 -            Log.shared.errorAndCrash(
     9.8 -                component: #function,
     9.9 -                errorString: "Mandatory field \"name\" not set in cdFolder: \(cdFolder)")
    9.10 +            Log.shared.errorAndCrash("Mandatory field \"name\" not set in cdFolder: %@)", cdFolder)
    9.11          }
    9.12  
    9.13          let f = Folder(name: cdFolder.name ?? "Serious Problem!",
    9.14 @@ -110,7 +108,7 @@
    9.15          }
    9.16          let p = NSPredicate(format: "%K = %@", CdFolder.RelationshipName.account, cdAcc)
    9.17          guard let cdFolders = CdFolder.all(predicate: p) as? [CdFolder] else {
    9.18 -            Log.shared.errorAndCrash(component: #function, errorString: "Error casting")
    9.19 +            Log.shared.errorAndCrash("Error casting")
    9.20              return result
    9.21          }
    9.22          result = cdFolders.map { $0.folder()}
    9.23 @@ -290,7 +288,7 @@
    9.24          let context = Record.Context.default
    9.25          context.performAndWait {
    9.26              guard let cdDeletee = cdFolder() else {
    9.27 -                Log.shared.errorAndCrash(component: #function, errorString: "That _is_ a problem")
    9.28 +                Log.shared.errorAndCrash("That _is_ a problem")
    9.29                  return
    9.30              }
    9.31              cdDeletee.delete(context: context)
    10.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Identity.swift	Fri May 03 12:19:46 2019 +0200
    10.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Identity.swift	Mon May 20 16:30:04 2019 +0200
    10.3 @@ -120,7 +120,7 @@
    10.4  
    10.5      public func save() {
    10.6          guard let saved = CdIdentity.save(self) as? CdIdentity else {
    10.7 -            Log.shared.errorAndCrash(component: #function, errorString: "No identity")
    10.8 +            Log.shared.errorAndCrash("No identity")
    10.9              return
   10.10          }
   10.11          takeOverValuesSetByCoreData(cdIdentity: saved)
    11.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Message.swift	Fri May 03 12:19:46 2019 +0200
    11.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Message.swift	Mon May 20 16:30:04 2019 +0200
    11.3 @@ -195,14 +195,11 @@
    11.4                            folderName: String,
    11.5                            accountAddress: String, includingDeleted: Bool = false) -> Message? {
    11.6          guard let account = Account.by(address: accountAddress) else {
    11.7 -            Log.shared.error(component: "Model",
    11.8 -                             errorString: "no account by email \(accountAddress)")
    11.9 +            Log.shared.error("no account by email %@", accountAddress)
   11.10              return nil
   11.11          }
   11.12          guard let cdAccount = account.cdAccount() else {
   11.13 -            Log.shared.error(
   11.14 -                component: "Model",
   11.15 -                errorString: "could not convert account (\(accountAddress)) to CdAccount")
   11.16 +            Log.shared.error("could not convert account (%@) to CdAccount", accountAddress)
   11.17              return nil
   11.18          }
   11.19          guard let cdMessage = CdMessage.search(uid: Int32(uid),
    12.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Server.swift	Fri May 03 12:19:46 2019 +0200
    12.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/Server.swift	Mon May 20 16:30:04 2019 +0200
    12.3 @@ -8,7 +8,7 @@
    12.4  
    12.5  import UIKit
    12.6  
    12.7 -open class Server : ModelSaveProtocol{
    12.8 +open class Server: ModelSaveProtocol {
    12.9      public enum ServerType: Int16 {
   12.10          case imap = 0
   12.11          case smtp
   12.12 @@ -72,14 +72,24 @@
   12.13          }
   12.14      }
   12.15  
   12.16 -    private var _trusted = false
   12.17 -    open var trusted: Bool {
   12.18 +    private var _automaticallyTrusted = false
   12.19 +    open var automaticallyTrusted: Bool {
   12.20          get{
   12.21              // Only IMAP servers can be trusted.
   12.22 -            return serverType == .imap ? _trusted : false
   12.23 +            return serverType == .imap ? _automaticallyTrusted : false
   12.24          }
   12.25          set{
   12.26 -            _trusted = newValue
   12.27 +            _automaticallyTrusted = newValue
   12.28 +        }
   12.29 +    }
   12.30 +    private var _manuallyTrusted = false
   12.31 +    open var manuallyTrusted: Bool {
   12.32 +        get{
   12.33 +            // Only IMAP servers can be trusted.
   12.34 +            return serverType == .imap ? _manuallyTrusted : false
   12.35 +        }
   12.36 +        set{
   12.37 +            _manuallyTrusted = newValue
   12.38          }
   12.39      }
   12.40      open var serverType: ServerType
   12.41 @@ -101,22 +111,26 @@
   12.42      /// - Returns: server instance with given data
   12.43      public static func create(serverType: ServerType, port: UInt16, address: String,
   12.44                              transport: Transport?, authMethod: String? = nil,
   12.45 -                            trusted: Bool = false, credentials: ServerCredentials) -> Server {
   12.46 +                            automaticallyTrusted: Bool = false,
   12.47 +                            manuallyTrusted: Bool = false,
   12.48 +                            credentials: ServerCredentials) -> Server {
   12.49          return create(serverType: serverType, port: port, address: address,
   12.50 -                      transport: transport, authMethod: authMethod, trusted: trusted,
   12.51 -                      credentials: credentials, toPersist: false)
   12.52 +                      transport: transport, authMethod: authMethod,
   12.53 +                      automaticallyTrusted: automaticallyTrusted,
   12.54 +                      manuallyTrusted: manuallyTrusted, credentials: credentials, toPersist: false)
   12.55      }
   12.56  
   12.57      private static func create(serverType: ServerType, port: UInt16, address: String,
   12.58                                 transport: Transport?, authMethod: String? = nil,
   12.59 -                               trusted: Bool = false,  credentials: ServerCredentials,
   12.60 -                               toPersist: Bool = true) -> Server {
   12.61 +                               automaticallyTrusted: Bool = false, manuallyTrusted: Bool = false,
   12.62 +                               credentials: ServerCredentials,toPersist: Bool = true) -> Server {
   12.63          let server = Server(serverType: serverType,
   12.64                                   port: port,
   12.65                                   address: address,
   12.66                                   transport: transport,
   12.67                                   authMethod: authMethod,
   12.68 -                                 trusted: trusted,
   12.69 +                                 automaticallyTrusted: automaticallyTrusted,
   12.70 +                                 manuallyTrusted: manuallyTrusted,
   12.71                                   credentials: credentials)
   12.72          if toPersist {
   12.73              CdServer.save(server)
   12.74 @@ -152,12 +166,14 @@
   12.75          self.address = server.address
   12.76          self.transport = server.transport
   12.77          self.authMethod = server.authMethod
   12.78 -        self.trusted = server.trusted
   12.79 +        self.automaticallyTrusted = server.automaticallyTrusted
   12.80 +        self.manuallyTrusted = server.manuallyTrusted
   12.81          self.credentials.updateValues(with: server.credentials)
   12.82      }
   12.83  
   12.84      private init(serverType: ServerType, port: UInt16, address: String,
   12.85 -                 transport: Transport?, authMethod: String? = nil, trusted: Bool = false,
   12.86 +                 transport: Transport?, authMethod: String? = nil,
   12.87 +                 automaticallyTrusted: Bool = false, manuallyTrusted: Bool = false,
   12.88                   credentials: ServerCredentials) {
   12.89          self.serverType = serverType
   12.90          self.port = port
   12.91 @@ -165,12 +181,15 @@
   12.92          self.transport = transport
   12.93          self.authMethod = authMethod
   12.94          self.credentials = credentials
   12.95 -        self.trusted = trusted
   12.96 +        self.automaticallyTrusted = automaticallyTrusted
   12.97 +        self.manuallyTrusted = manuallyTrusted
   12.98      }
   12.99  
  12.100      public convenience init(withDataFrom server: Server) {
  12.101          self.init(serverType: server.serverType, port: server.port, address: server.address,
  12.102 -                  transport: server.transport, authMethod: server.authMethod, trusted: server.trusted,
  12.103 +                  transport: server.transport, authMethod: server.authMethod,
  12.104 +                  automaticallyTrusted: server.automaticallyTrusted,
  12.105 +                  manuallyTrusted: server.manuallyTrusted,
  12.106                    credentials: ServerCredentials(withDataFrom: server.credentials))
  12.107      }
  12.108  
  12.109 @@ -191,7 +210,8 @@
  12.110                              address: cdAddress,
  12.111                              transport: cdServer.transport,
  12.112                              authMethod: cdServer.authMethod,
  12.113 -                            trusted: cdServer.trusted,
  12.114 +                            automaticallyTrusted: cdServer.automaticallyTrusted,
  12.115 +                            manuallyTrusted: cdServer.manuallyTrusted,
  12.116                              credentials: creds)
  12.117          return s
  12.118      }
    13.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/ServerCredentials.swift	Fri May 03 12:19:46 2019 +0200
    13.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Interface/ServerCredentials.swift	Mon May 20 16:30:04 2019 +0200
    13.3 @@ -36,8 +36,7 @@
    13.4      public static func create(cdServerCredentials: CdServerCredentials) -> ServerCredentials {
    13.5          guard let loginName = cdServerCredentials.loginName,
    13.6          let key = cdServerCredentials.key else {
    13.7 -                Log.shared.errorAndCrash(component: #function,
    13.8 -                                         errorString:
    13.9 +                Log.shared.errorAndCrash(
   13.10                      "Incomplete cdServerCredentials. No username or key.")
   13.11                  return ServerCredentials(loginName: "Invalid User created by \(#function)")
   13.12          }
    14.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Internal/Record/CdServer+Extensions.swift	Fri May 03 12:19:46 2019 +0200
    14.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Internal/Record/CdServer+Extensions.swift	Mon May 20 16:30:04 2019 +0200
    14.3 @@ -14,7 +14,7 @@
    14.4      open var serverType: Server.ServerType {
    14.5          get {
    14.6              guard let type = Server.ServerType(rawValue: self.serverTypeRawValue) else {
    14.7 -                Log.shared.errorAndCrash(component: #function, errorString: "No server type?!")
    14.8 +                Log.shared.errorAndCrash("No server type?!")
    14.9                  //this does not make sense as a default value, but as serverTypeRawValue is non-optional, this guard should never fail
   14.10                  return Server.ServerType.imap
   14.11              }
   14.12 @@ -28,7 +28,7 @@
   14.13      open var transport: Server.Transport {
   14.14          get {
   14.15              guard let type = Server.Transport(rawValue: self.transportRawValue) else {
   14.16 -                Log.shared.errorAndCrash(component: #function, errorString: "No server transport?!")
   14.17 +                Log.shared.errorAndCrash("No server transport?!")
   14.18                  return Server.Transport.plain
   14.19              }
   14.20              return type
    15.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Internal/Record/NSManagedObjectContext+Extension.swift	Fri May 03 12:19:46 2019 +0200
    15.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Internal/Record/NSManagedObjectContext+Extension.swift	Mon May 20 16:30:04 2019 +0200
    15.3 @@ -20,8 +20,7 @@
    15.4              do {
    15.5                  try save()
    15.6              } catch {
    15.7 -                Log.shared.errorAndCrash(component: "#file - \(#function)[\(#line)]",
    15.8 -                    errorString: "\(error)")
    15.9 +                Log.shared.errorAndCrash("%@", error.localizedDescription)
   15.10              }
   15.11          }
   15.12      }
   15.13 @@ -42,9 +41,7 @@
   15.14                          try save()
   15.15                      } catch {
   15.16                          let err = error as NSError
   15.17 -                        Log.shared.error(
   15.18 -                            component: #function,
   15.19 -                            errorString: "*** \(err.domain), \(err.code):\n*** \(err)")
   15.20 +                        Log.shared.error("%@", err)
   15.21                          if err.domain == NSCocoaErrorDomain && err.code == 133020 {
   15.22                              // merge conflict, refresh and try again
   15.23                              refresh(object, mergeChanges: false)
   15.24 @@ -55,8 +52,7 @@
   15.25                  }
   15.26              }
   15.27          } catch {
   15.28 -            Log.shared.errorAndCrash(component: "#file - \(#function)[\(#line)]",
   15.29 -                errorString: "\(error)")
   15.30 +            Log.shared.errorAndCrash("%@", error.localizedDescription)
   15.31          }
   15.32      }
   15.33  }
    16.1 --- a/MessageModel/MessageModel/Interface/MessageModelObjects/Internal/Record/Query.swift	Fri May 03 12:19:46 2019 +0200
    16.2 +++ b/MessageModel/MessageModel/Interface/MessageModelObjects/Internal/Record/Query.swift	Mon May 20 16:30:04 2019 +0200
    16.3 @@ -554,7 +554,7 @@
    16.4          do {
    16.5              count = try moc.count(for: request)
    16.6          } catch {
    16.7 -            Log.shared.errorAndCrash(component: "#file - \(#function)[\(#line)]", errorString: "\(error)")
    16.8 +            Log.shared.errorAndCrash("%@", error.localizedDescription)
    16.9          }
   16.10  
   16.11          return count
   16.12 @@ -710,8 +710,7 @@
   16.13                      batchResult = result
   16.14                  }
   16.15              } catch {
   16.16 -                Log.shared.errorAndCrash(component: "#file - \(#function)[\(#line)]",
   16.17 -                    errorString: "\(error)")
   16.18 +                Log.shared.errorAndCrash("%@", error.localizedDescription)
   16.19              }
   16.20          }
   16.21  
    17.1 --- a/MessageModel/MessageModel/Interface/MessageQueryResults/MessageQueryResults.swift	Fri May 03 12:19:46 2019 +0200
    17.2 +++ b/MessageModel/MessageModel/Interface/MessageQueryResults/MessageQueryResults.swift	Mon May 20 16:30:04 2019 +0200
    17.3 @@ -92,8 +92,7 @@
    17.4              do {
    17.5                  return try getMessage(forIndex: index)
    17.6              } catch{
    17.7 -                Log.shared.error(component: getComponentName(),
    17.8 -                                 errorString: "Fail to get message for subscript")
    17.9 +                Log.shared.error("Fail to get message for subscript")
   17.10                  fatalError("Fail to get message for subscript")
   17.11              }
   17.12          }
   17.13 @@ -149,8 +148,8 @@
   17.14  private extension MessageQueryResults {
   17.15      private func get(indexPath: IndexPath?, forType type: NSFetchedResultsChangeType) -> IndexPath? {
   17.16          guard let indexPath = indexPath else {
   17.17 -            Log.shared.errorAndCrash(component: getComponentName(),
   17.18 -                    errorString: "QuerryResultController indexPath for NSFetchedResultsChangeType: \(type), should never be nil")
   17.19 +            let error = "QuerryResultController indexPath for NSFetchedResultsChangeType: \(type.rawValue), should never be nil"
   17.20 +            Log.shared.errorAndCrash("%@", error)
   17.21              return nil
   17.22          }
   17.23          return indexPath
   17.24 @@ -164,10 +163,6 @@
   17.25          return message
   17.26      }
   17.27  
   17.28 -    private func getComponentName() -> String {
   17.29 -        return String(describing: type(of: self))
   17.30 -    }
   17.31 -
   17.32      private func getCacheName() -> String {
   17.33          var cacheHash = folder.hashValue
   17.34          if let filter = filter { cacheHash = filter.hashValue ^ cacheHash}
   17.35 @@ -192,7 +187,7 @@
   17.36  
   17.37      private func getFolderPredicate() -> NSPredicate? {
   17.38          guard let cdFolder = folder.cdFolder() else {
   17.39 -            MMLog.shared.errorAndCrash("Fail to convert Folder to CdFolder")
   17.40 +            Log.shared.errorAndCrash("Fail to convert Folder to CdFolder")
   17.41              return nil
   17.42          }
   17.43          return CdMessage.PredicateFactory.belongingToParentFolder(parentFolder: cdFolder)
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/MessageModel/MessageModel/Interface/VerifiableAccount/VerifiableAccount.swift	Mon May 20 16:30:04 2019 +0200
    18.3 @@ -0,0 +1,379 @@
    18.4 +//
    18.5 +//  VerifiableAccount.swift
    18.6 +//  pEpForiOS
    18.7 +//
    18.8 +//  Created by buff on 04.08.17.
    18.9 +//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   18.10 +//
   18.11 +
   18.12 +import PantomimeFramework
   18.13 +import CoreData
   18.14 +
   18.15 +public class VerifiableAccount: VerifiableAccountProtocol {
   18.16 +    // MARK: - VerifiableAccountProtocol (data)
   18.17 +
   18.18 +    public weak var verifiableAccountDelegate: VerifiableAccountDelegate?
   18.19 +
   18.20 +    public var address: String?
   18.21 +
   18.22 +    /**
   18.23 +     The actual name of the user, or nick name. Not to be confused with the login name.
   18.24 +     */
   18.25 +    public var userName: String?
   18.26 +
   18.27 +    /**
   18.28 +     An optional name for the servers, if needed.
   18.29 +     */
   18.30 +    public var loginName: String?
   18.31 +
   18.32 +    /**
   18.33 +     Currently, the only use case for this is .saslXoauth2. In all other cases,
   18.34 +     this should be nil.
   18.35 +     */
   18.36 +    public var authMethod: AuthMethod?
   18.37 +
   18.38 +    public var password: String?
   18.39 +
   18.40 +    /**
   18.41 +     If the user chose OAuth2, this is the token. `password` then should be nil.
   18.42 +     */
   18.43 +    public var accessToken: OAuth2AccessTokenProtocol?
   18.44 +
   18.45 +    public var serverIMAP: String?
   18.46 +    public var portIMAP: UInt16 = 993
   18.47 +    public var transportIMAP = ConnectionTransport.TLS
   18.48 +    public var serverSMTP: String?
   18.49 +    public var portSMTP: UInt16 = 587
   18.50 +    public var transportSMTP = ConnectionTransport.startTLS
   18.51 +
   18.52 +    public var isAutomaticallyTrustedImapServer: Bool
   18.53 +    public var isManuallyTrustedImapServer: Bool
   18.54 +
   18.55 +    public init(verifiableAccountDelegate: VerifiableAccountDelegate?,
   18.56 +                address: String?,
   18.57 +                userName: String?,
   18.58 +                loginName: String?,
   18.59 +                authMethod: AuthMethod?,
   18.60 +                password: String?,
   18.61 +                accessToken: OAuth2AccessTokenProtocol?,
   18.62 +                serverIMAP: String?,
   18.63 +                portIMAP: UInt16,
   18.64 +                transportIMAP: ConnectionTransport,
   18.65 +                serverSMTP: String?,
   18.66 +                portSMTP: UInt16,
   18.67 +                transportSMTP: ConnectionTransport,
   18.68 +                automaticallyTrustedImapServer: Bool,
   18.69 +                manuallyTrustedImapServer: Bool) {
   18.70 +        self.verifiableAccountDelegate = verifiableAccountDelegate
   18.71 +        self.address = address
   18.72 +        self.userName = userName
   18.73 +        self.loginName = loginName
   18.74 +        self.authMethod = authMethod
   18.75 +        self.password = password
   18.76 +        self.accessToken = accessToken
   18.77 +        self.serverIMAP = serverIMAP
   18.78 +        self .portIMAP = portIMAP
   18.79 +        self.transportIMAP = transportIMAP
   18.80 +        self.serverSMTP = serverSMTP
   18.81 +        self.portSMTP = portSMTP
   18.82 +        self.transportSMTP = transportSMTP
   18.83 +        self.isAutomaticallyTrustedImapServer = automaticallyTrustedImapServer
   18.84 +        self.isManuallyTrustedImapServer = manuallyTrustedImapServer
   18.85 +    }
   18.86 +
   18.87 +    public convenience init() {
   18.88 +        self.init(verifiableAccountDelegate: nil,
   18.89 +                  address: nil,
   18.90 +                  userName: nil,
   18.91 +                  loginName: nil,
   18.92 +                  authMethod: nil,
   18.93 +                  password: nil,
   18.94 +                  accessToken: nil,
   18.95 +                  serverIMAP: nil,
   18.96 +                  portIMAP: 993,
   18.97 +                  transportIMAP: ConnectionTransport.TLS,
   18.98 +                  serverSMTP: nil,
   18.99 +                  portSMTP: 587,
  18.100 +                  transportSMTP: ConnectionTransport.startTLS,
  18.101 +                  automaticallyTrustedImapServer: false,
  18.102 +                  manuallyTrustedImapServer: false)
  18.103 +    }
  18.104 +
  18.105 +    // MARK: - VerifiableAccountProtocol (behavior)
  18.106 +
  18.107 +    private func isValid() -> Bool {
  18.108 +        let isValid =
  18.109 +            isValidName &&
  18.110 +                (address?.count ?? 0) > 0 &&
  18.111 +                ((authMethod == .saslXoauth2 && accessToken != nil && password == nil) ||
  18.112 +                    (accessToken == nil && password != nil)) &&
  18.113 +                portIMAP > 0 &&
  18.114 +                portSMTP > 0 &&
  18.115 +                (serverIMAP?.count ?? 0) > 0 &&
  18.116 +                (serverSMTP?.count ?? 0) > 0
  18.117 +        return isValid
  18.118 +    }
  18.119 +
  18.120 +    private func startImapVerification() throws {
  18.121 +        let theVerifier = VerifiableAccountIMAP()
  18.122 +        self.imapVerifier = theVerifier
  18.123 +        theVerifier.verifiableAccountDelegate = self
  18.124 +        guard let imapConnectInfo = BasicConnectInfo(
  18.125 +            verifiableAccount: self, emailProtocol: .imap) else {
  18.126 +                // Assuming this is caused by invalid data.
  18.127 +                throw VerifiableAccountValidationError.invalidUserData
  18.128 +        }
  18.129 +        theVerifier.verify(basicConnectInfo: imapConnectInfo)
  18.130 +    }
  18.131 +
  18.132 +    private func startSmtpVerification() throws {
  18.133 +        let theVerifier = VerifiableAccountSMTP()
  18.134 +        self.smtpVerifier = theVerifier
  18.135 +        theVerifier.verifiableAccountDelegate = self
  18.136 +        guard let smtpConnectInfo = BasicConnectInfo(
  18.137 +            verifiableAccount: self, emailProtocol: .smtp) else {
  18.138 +                // Assuming this is caused by invalid data.
  18.139 +                throw VerifiableAccountValidationError.invalidUserData
  18.140 +        }
  18.141 +        theVerifier.verify(basicConnectInfo: smtpConnectInfo)
  18.142 +    }
  18.143 +
  18.144 +    public func verify() throws {
  18.145 +        imapResult = nil
  18.146 +        smtpResult = nil
  18.147 +
  18.148 +        if !isValid() {
  18.149 +            throw VerifiableAccountValidationError.invalidUserData
  18.150 +        }
  18.151 +
  18.152 +        try startImapVerification()
  18.153 +        try startSmtpVerification()
  18.154 +    }
  18.155 +
  18.156 +    public func save() throws {
  18.157 +        if !isValid() {
  18.158 +            throw VerifiableAccountValidationError.invalidUserData
  18.159 +        }
  18.160 +
  18.161 +        guard let addressImap = serverIMAP else {
  18.162 +            throw VerifiableAccountValidationError.invalidUserData
  18.163 +        }
  18.164 +
  18.165 +        guard let addressSmtp = serverSMTP else {
  18.166 +            throw VerifiableAccountValidationError.invalidUserData
  18.167 +        }
  18.168 +
  18.169 +        let moc = Record.Context.background
  18.170 +
  18.171 +        moc.performAndWait {
  18.172 +            let cdIdentity = updateOrCreateOwnIdentity(context: moc,
  18.173 +                                                       address: address,
  18.174 +                                                       userName: userName)
  18.175 +
  18.176 +            let cdAccount = findOrCreateAccount(context: moc, identity: cdIdentity)
  18.177 +
  18.178 +            let theImapServer = update(
  18.179 +                server: cdAccount.imapCdServer ?? CdServer.create(context: moc),
  18.180 +                address: addressImap,
  18.181 +                port: portIMAP,
  18.182 +                serverType: .imap,
  18.183 +                authMethod: authMethod,
  18.184 +                automaticallyTrusted: isAutomaticallyTrustedImapServer,
  18.185 +                manuallyTrusted: isManuallyTrustedImapServer,
  18.186 +                transport: transportIMAP)
  18.187 +
  18.188 +            let theSmtpServer = update(
  18.189 +                server: cdAccount.smtpCdServer ?? CdServer.create(context: moc),
  18.190 +                address: addressSmtp,
  18.191 +                port: portSMTP,
  18.192 +                serverType: .smtp,
  18.193 +                authMethod: authMethod,
  18.194 +                automaticallyTrusted: false,
  18.195 +                manuallyTrusted: false,
  18.196 +                transport: transportSMTP)
  18.197 +
  18.198 +            let credentialsImap = update(
  18.199 +                credentials: theImapServer.credentials ?? CdServerCredentials.create(context: moc),
  18.200 +                loginName: loginName,
  18.201 +                address: address,
  18.202 +                password: password,
  18.203 +                accessToken: accessToken)
  18.204 +            credentialsImap.servers = NSSet(array: [theImapServer])
  18.205 +            theImapServer.credentials = credentialsImap
  18.206 +
  18.207 +            let credentialsSmtp = update(
  18.208 +                credentials: theSmtpServer.credentials ?? CdServerCredentials.create(context: moc),
  18.209 +                loginName: loginName,
  18.210 +                address: address,
  18.211 +                password: password,
  18.212 +                accessToken: accessToken)
  18.213 +            credentialsSmtp.servers = NSSet(array: [theSmtpServer])
  18.214 +            theSmtpServer.credentials = credentialsSmtp
  18.215 +
  18.216 +            cdAccount.servers = NSSet(array: [theImapServer, theSmtpServer])
  18.217 +
  18.218 +            moc.saveAndLogErrors()
  18.219 +        }
  18.220 +    }
  18.221 +
  18.222 +    // MARK: - UI support
  18.223 +
  18.224 +    public var isValidName: Bool {
  18.225 +        return (userName?.count ?? 0) >= 1
  18.226 +    }
  18.227 +
  18.228 +    public var isValidUser: Bool {
  18.229 +        return isValidName && isValidEmail && isValidPassword
  18.230 +    }
  18.231 +
  18.232 +    private var isValidEmail: Bool {
  18.233 +        return address?.isProbablyValidEmail() ?? false
  18.234 +    }
  18.235 +
  18.236 +    private var isValidPassword: Bool {
  18.237 +        if let pass = password {
  18.238 +            return pass.count > 0
  18.239 +        }
  18.240 +        return false
  18.241 +    }
  18.242 +
  18.243 +    // MARK: - Internal (data)
  18.244 +
  18.245 +    private var imapVerifier: VerifiableAccountIMAP?
  18.246 +    private var smtpVerifier: VerifiableAccountSMTP?
  18.247 +
  18.248 +    var imapResult: Result<Void, Error>? = nil
  18.249 +    var smtpResult: Result<Void, Error>? = nil
  18.250 +
  18.251 +    /// Used for synchronizing the 2 asynchronous results (IMAP and SMTP verification).
  18.252 +    private let syncQueue = DispatchQueue(label: "VerifiableAccountSynchronization")
  18.253 +
  18.254 +    // MARK: - Internal helpers for saving
  18.255 +
  18.256 +    private func findOrCreateAccount(context: NSManagedObjectContext,
  18.257 +                                     identity: CdIdentity) -> CdAccount {
  18.258 +        let p = NSPredicate(
  18.259 +            format: "%K = %@" , CdAccount.RelationshipName.identity, identity)
  18.260 +        if let cdAccount = CdAccount.first(predicate: p, in: context) {
  18.261 +            return cdAccount
  18.262 +        } else {
  18.263 +            let cdAccount = CdAccount.create(context: context)
  18.264 +            cdAccount.identity = identity
  18.265 +            return cdAccount
  18.266 +        }
  18.267 +    }
  18.268 +
  18.269 +    private func updateOrCreateOwnIdentity(context: NSManagedObjectContext,
  18.270 +                                           address: String?,
  18.271 +                                           userName: String?) -> CdIdentity {
  18.272 +        if let theAddress = address,
  18.273 +            let identity = CdIdentity.search(address: theAddress) {
  18.274 +            update(identity: identity, address: address, userName: userName)
  18.275 +            return identity
  18.276 +        } else {
  18.277 +        let cdId = CdIdentity.create(context: context)
  18.278 +            update(identity: cdId, address: address, userName: userName)
  18.279 +            return cdId
  18.280 +        }
  18.281 +    }
  18.282 +
  18.283 +    private func update(identity: CdIdentity,
  18.284 +                        address: String?,
  18.285 +                        userName: String?) {
  18.286 +        identity.address = address
  18.287 +        identity.userName = userName
  18.288 +        identity.userID = identity.userID ?? CdIdentity.pEpOwnUserID
  18.289 +    }
  18.290 +
  18.291 +    /// Updates credentials with the given parameters.
  18.292 +    ///
  18.293 +    /// - Note: There is either an ordinary password, so a key chain entry
  18.294 +    ///         gets produced, or an access token (for OAUTH2),
  18.295 +    ///         in which case the token gets persisted into the key chain.
  18.296 +    private func update(credentials: CdServerCredentials,
  18.297 +                        loginName: String?,
  18.298 +                        address: String?,
  18.299 +                        password: String?,
  18.300 +                        accessToken: OAuth2AccessTokenProtocol?) -> CdServerCredentials {
  18.301 +        credentials.loginName = loginName ?? address
  18.302 +
  18.303 +        var payload: String? = nil
  18.304 +        if let token = accessToken {
  18.305 +            payload = token.persistBase64Encoded()
  18.306 +        } else {
  18.307 +            payload = password
  18.308 +        }
  18.309 +
  18.310 +        // Reuse key, or create a new one.
  18.311 +        // In any case, update the payload (the password or a current OAUTH2 token).
  18.312 +        let keyChainId = credentials.key ?? UUID().uuidString
  18.313 +        credentials.key = keyChainId
  18.314 +        KeyChain.updateCreateOrDelete(password: payload, forKey: keyChainId)
  18.315 +
  18.316 +        return credentials
  18.317 +    }
  18.318 +
  18.319 +    private func update(server: CdServer,
  18.320 +                        address: String,
  18.321 +                        port: UInt16,
  18.322 +                        serverType: Server.ServerType,
  18.323 +                        authMethod: AuthMethod?,
  18.324 +                        automaticallyTrusted: Bool,
  18.325 +                        manuallyTrusted: Bool,
  18.326 +                        transport: ConnectionTransport) -> CdServer {
  18.327 +        server.address = address
  18.328 +        server.port = NSNumber.init(value: port)
  18.329 +        server.authMethod = authMethod?.rawValue
  18.330 +        server.serverType = serverType
  18.331 +        server.automaticallyTrusted = automaticallyTrusted
  18.332 +        server.manuallyTrusted = manuallyTrusted
  18.333 +        server.transport = transport.toServerTransport()
  18.334 +        server.serverType = serverType
  18.335 +
  18.336 +        return server
  18.337 +    }
  18.338 +
  18.339 +    // MARK: - Internal delegate helpers
  18.340 +
  18.341 +    private func checkSuccess() {
  18.342 +        guard let theImapResult = imapResult, let theSmtpResult = smtpResult else {
  18.343 +            return
  18.344 +        }
  18.345 +
  18.346 +        switch theImapResult {
  18.347 +        case .failure(let error):
  18.348 +            verifiableAccountDelegate?.didEndVerification(result: .failure(error))
  18.349 +        case .success(()):
  18.350 +            switch theSmtpResult {
  18.351 +            case .failure(let error):
  18.352 +                verifiableAccountDelegate?.didEndVerification(result: .failure(error))
  18.353 +            case .success(()):
  18.354 +                verifiableAccountDelegate?.didEndVerification(result: .success(()))
  18.355 +            }
  18.356 +        }
  18.357 +    }
  18.358 +}
  18.359 +
  18.360 +extension VerifiableAccount: VerifiableAccountIMAPDelegate {
  18.361 +    func verified(verifier: VerifiableAccountIMAP,
  18.362 +                  basicConnectInfo: BasicConnectInfo,
  18.363 +                  result: Result<Void, Error>) {
  18.364 +        verifier.verifiableAccountDelegate = nil
  18.365 +        syncQueue.async { [weak self] in
  18.366 +            self?.imapResult = result
  18.367 +            self?.checkSuccess()
  18.368 +        }
  18.369 +    }
  18.370 +}
  18.371 +
  18.372 +extension VerifiableAccount: VerifiableAccountSMTPDelegate {
  18.373 +    func verified(verifier: VerifiableAccountSMTP,
  18.374 +                  basicConnectInfo: BasicConnectInfo,
  18.375 +                  result: Result<Void, Error>) {
  18.376 +        verifier.verifiableAccountDelegate = nil
  18.377 +        syncQueue.async { [weak self] in
  18.378 +            self?.smtpResult = result
  18.379 +            self?.checkSuccess()
  18.380 +        }
  18.381 +    }
  18.382 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/MessageModel/MessageModel/Interface/VerifiableAccount/VerifiableAccountProtocol.swift	Mon May 20 16:30:04 2019 +0200
    19.3 @@ -0,0 +1,112 @@
    19.4 +//
    19.5 +//  VerifiableAccountProtocol.swift
    19.6 +//  MessageModel
    19.7 +//
    19.8 +//  Created by Dirk Zimmermann on 15.04.19.
    19.9 +//  Copyright © 2019 pEp Security S.A. All rights reserved.
   19.10 +//
   19.11 +
   19.12 +import Foundation
   19.13 +
   19.14 +import PantomimeFramework
   19.15 +
   19.16 +/// A type of known error that can be thrown by implementations
   19.17 +/// when input data is incomplete or inconsistent.
   19.18 +public enum VerifiableAccountValidationError: Error {
   19.19 +    case invalidUserData
   19.20 +}
   19.21 +
   19.22 +/// The delegate used for the `VerifiableAccountProtocol`.
   19.23 +public protocol VerifiableAccountDelegate: class {
   19.24 +    /// Gets called once the verification has finished, successfully or not.
   19.25 +    /// The given `result` indicates success or failure.
   19.26 +    func didEndVerification(result: Result<Void, Error>)
   19.27 +}
   19.28 +
   19.29 +/// Objects that can verify accounts.
   19.30 +/// An account currently consist of user data (like login, password etc.)
   19.31 +/// and one IMAP and one SMTP server.
   19.32 +///
   19.33 +/// 1. Fill-in the data, like email address, server names etc.
   19.34 +/// 2. Set the delegate to a class under your control.
   19.35 +/// 3. Call `verify()`. This will throw if the given data is inconsistent.
   19.36 +/// 4. Your delegate will get called when the verification is finished, indicating
   19.37 +///    either success of failure.
   19.38 +/// 5. On success, call `save()` to persist this account.
   19.39 +///    `save()` will throw in any case `verify()` will throw (inconsistent data),
   19.40 +///    or when the verification was not successful.
   19.41 +public protocol VerifiableAccountProtocol {
   19.42 +    /// The email address of the account. Used for logging in to the servers.
   19.43 +    var address: String? { get set }
   19.44 +
   19.45 +    /// The actual name of the user, or nick name.
   19.46 +    /// Not to be confused with the login name.
   19.47 +    var userName: String? { get set }
   19.48 +
   19.49 +    /// An optional login name for the servers, if needed.
   19.50 +    /// Falls back to `address`.
   19.51 +    var loginName: String? { get set }
   19.52 +
   19.53 +    /// Currently, the only use case for this is `.saslXoauth2`.
   19.54 +    /// In all other cases, this should be nil.
   19.55 +    /// Valid for both IMAP and SMTP servers.
   19.56 +    var authMethod: AuthMethod? { get set }
   19.57 +
   19.58 +    /// The password, if needed, to log in.
   19.59 +    /// Valid for both IMAP and SMTP servers.
   19.60 +    var password: String? { get set }
   19.61 +
   19.62 +    /// If the user chose OAuth2, this is the token. `password` then must be nil.
   19.63 +    /// If set, `authMethod` must be `.saslXoauth2`
   19.64 +    /// Valid for both IMAP and SMTP servers.
   19.65 +    /// - Note: For accounts that require it, this token must be valid or otherwise
   19.66 +    ///         Verification will fail.
   19.67 +    var accessToken: OAuth2AccessTokenProtocol? { get set }
   19.68 +
   19.69 +    /// The address of the IMAP server, like 'imap.example.com'.
   19.70 +    var serverIMAP: String? { get set }
   19.71 +
   19.72 +    /// The port the IMAP server listens on for new connections.
   19.73 +    var portIMAP: UInt16 { get set }
   19.74 +
   19.75 +    /// The transport to be used for IMAP, like TLS.
   19.76 +    var transportIMAP: ConnectionTransport { get set }
   19.77 +
   19.78 +    /// The address of the SMTP server, like 'smtp.example.com'.
   19.79 +    var serverSMTP: String? { get set }
   19.80 +
   19.81 +    /// The port the SMTP server listens on for new connections.
   19.82 +    var portSMTP: UInt16 { get set }
   19.83 +
   19.84 +    /// The transport to be used for SMTP, like TLS.
   19.85 +    var transportSMTP: ConnectionTransport { get set }
   19.86 +
   19.87 +    /// Indicates that the IMAP server is to be automaticallyTrusted.
   19.88 +    var isAutomaticallyTrustedImapServer: Bool { get set }
   19.89 +
   19.90 +    /// Indicates that the IMAP server is to be manuallyTrusted.
   19.91 +    var isManuallyTrustedImapServer: Bool { get set }
   19.92 +
   19.93 +    /// The delegate to inform when the process has finished, either successfully or not.
   19.94 +    var verifiableAccountDelegate: VerifiableAccountDelegate? { get set }
   19.95 +
   19.96 +    /// Starts login attempts in the background to the indicated servers,
   19.97 +    /// informing the delegate (`verifiableAccountDelegate`) when finished.
   19.98 +    /// - Note: Throws for missing data.
   19.99 +    /// - Throws: VerifiableAccountValidationError
  19.100 +    func verify() throws
  19.101 +
  19.102 +    /// If the verification was successful, saves the account.
  19.103 +    /// - Note: Thows for missing data (i.e., all cases when `verify()` would throw),
  19.104 +    ///   and also if no successfull verification took place before.
  19.105 +    /// - Throws: VerifiableAccountValidationError
  19.106 +    func save() throws
  19.107 +
  19.108 +    // MARK: - UI support
  19.109 +
  19.110 +    /// The UI might want to know this, i.e. to decide which element is first responder.
  19.111 +    var isValidName: Bool { get }
  19.112 +
  19.113 +    /// The UI might want to know this, i.e. to decide which element is first responder.
  19.114 +    var isValidUser: Bool { get }
  19.115 +}
    20.1 --- a/MessageModel/MessageModel/Interface/VerificationService.swift	Fri May 03 12:19:46 2019 +0200
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,72 +0,0 @@
    20.4 -//
    20.5 -//  VerificationService.swift
    20.6 -//  pEpForiOS
    20.7 -//
    20.8 -//  Created by Dirk Zimmermann on 01.06.17.
    20.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   20.10 -//
   20.11 -
   20.12 -import Foundation
   20.13 -import CoreData
   20.14 -import pEpIOSToolbox
   20.15 -
   20.16 -public class VerificationService {
   20.17 -    private let parentName: String
   20.18 -    private let managementQueue = DispatchQueue(
   20.19 -        label: "pep.security.VerificationService.managementQueue",
   20.20 -        qos: .utility,
   20.21 -        target: nil)
   20.22 -    private var accountVerifications =
   20.23 -        [Account:(AccountVerificationService, AccountVerificationServiceDelegate)]()
   20.24 -
   20.25 -    public init(parentName: String = #function) {
   20.26 -        self.parentName = parentName
   20.27 -    }
   20.28 -}
   20.29 -
   20.30 -// MARK: - Private methods
   20.31 -extension VerificationService {
   20.32 -    private func requestVerificationInternal(account: Account,
   20.33 -                                             delegate: AccountVerificationServiceDelegate) {
   20.34 -        let service = AccountVerificationService()
   20.35 -        service.delegate = self
   20.36 -        accountVerifications[account] = (service, delegate)
   20.37 -        service.verify(account: account)
   20.38 -    }
   20.39 -}
   20.40 -
   20.41 -// MARK: - VerificationServiceProtocol
   20.42 -
   20.43 -extension VerificationService: VerificationServiceProtocol {
   20.44 -    /**
   20.45 -     Request account verification, receiving news via the delegate.
   20.46 -     Backend might start syncing the inbox as soon as the verification
   20.47 -     was successful.
   20.48 -     */
   20.49 -    public func requestVerification(account: Account, delegate: AccountVerificationServiceDelegate) {
   20.50 -        managementQueue.async {
   20.51 -            self.requestVerificationInternal(account: account, delegate: delegate)
   20.52 -        }
   20.53 -    }
   20.54 -}
   20.55 -
   20.56 -// MARK: - AccountVerificationServiceDelegate
   20.57 -
   20.58 -extension VerificationService: AccountVerificationServiceDelegate {
   20.59 -    private func verifiedInternal(account: Account, service: AccountVerificationServiceProtocol,
   20.60 -                                  result: AccountVerificationResult) {
   20.61 -        guard let (service, delegate) = accountVerifications[account] else {
   20.62 -            Logger.backendLogger.error("no service")
   20.63 -            return
   20.64 -        }
   20.65 -        delegate.verified(account: account, service: service, result: result)
   20.66 -        accountVerifications[account] = nil
   20.67 -    }
   20.68 -
   20.69 -    public func verified(account: Account, service: AccountVerificationServiceProtocol,
   20.70 -                         result: AccountVerificationResult) {
   20.71 -        managementQueue.async {
   20.72 -            self.verifiedInternal(account: account, service: service, result: result)
   20.73 -        }
   20.74 -    }
   20.75 -}
    21.1 --- a/MessageModel/MessageModel/MessageModel.xcdatamodeld/refactor0.1.xcdatamodel/contents	Fri May 03 12:19:46 2019 +0200
    21.2 +++ b/MessageModel/MessageModel/MessageModel.xcdatamodeld/refactor0.1.xcdatamodel/contents	Mon May 20 16:30:04 2019 +0200
    21.3 @@ -1,5 +1,5 @@
    21.4  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    21.5 -<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="18A391" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="refactor0.1">
    21.6 +<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14490.98" systemVersion="18D109" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="refactor0.1">
    21.7      <entity name="CdAccount" representedClassName="CdAccount" syncable="YES" codeGenerationType="class">
    21.8          <relationship name="folders" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="CdFolder" inverseName="account" inverseEntity="CdFolder" syncable="YES"/>
    21.9          <relationship name="identity" maxCount="1" deletionRule="Nullify" destinationEntity="CdIdentity" inverseName="accounts" inverseEntity="CdIdentity" syncable="YES"/>
   21.10 @@ -153,11 +153,12 @@
   21.11      <entity name="CdServer" representedClassName="CdServer" syncable="YES" codeGenerationType="class">
   21.12          <attribute name="address" attributeType="String" syncable="YES"/>
   21.13          <attribute name="authMethod" optional="YES" attributeType="String" syncable="YES"/>
   21.14 +        <attribute name="automaticallyTrusted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
   21.15          <attribute name="imapFolderSeparator" optional="YES" attributeType="String" syncable="YES"/>
   21.16 +        <attribute name="manuallyTrusted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
   21.17          <attribute name="port" attributeType="Integer 16" usesScalarValueType="NO" syncable="YES"/>
   21.18          <attribute name="serverTypeRawValue" attributeType="Integer 16" usesScalarValueType="YES" syncable="YES"/>
   21.19          <attribute name="transportRawValue" attributeType="Integer 16" usesScalarValueType="YES" syncable="YES"/>
   21.20 -        <attribute name="trusted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
   21.21          <relationship name="account" maxCount="1" deletionRule="Nullify" destinationEntity="CdAccount" inverseName="servers" inverseEntity="CdAccount" syncable="YES"/>
   21.22          <relationship name="credentials" maxCount="1" deletionRule="Cascade" destinationEntity="CdServerCredentials" inverseName="servers" inverseEntity="CdServerCredentials" syncable="YES"/>
   21.23      </entity>
   21.24 @@ -178,7 +179,7 @@
   21.25          <element name="CdMessage" positionX="151" positionY="27" width="128" height="420"/>
   21.26          <element name="CdMessageKeyword" positionX="0" positionY="171" width="128" height="73"/>
   21.27          <element name="CdMessageReference" positionX="-9" positionY="162" width="128" height="75"/>
   21.28 -        <element name="CdServer" positionX="-722" positionY="135" width="128" height="180"/>
   21.29 +        <element name="CdServer" positionX="-722" positionY="135" width="128" height="30"/>
   21.30          <element name="CdServerCredentials" positionX="-504" positionY="180" width="128" height="90"/>
   21.31      </elements>
   21.32  </model>
   21.33 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/MessageModel/MessageModel/Modules/Log/Log.swift	Mon May 20 16:30:04 2019 +0200
    22.3 @@ -0,0 +1,17 @@
    22.4 +//
    22.5 +//  Log.swift
    22.6 +//  MessageModel
    22.7 +//
    22.8 +//  Created by Andreas Buff on 01.03.19.
    22.9 +//  Copyright © 2019 pEp Security S.A. All rights reserved.
   22.10 +//
   22.11 +
   22.12 +import pEpIOSToolbox
   22.13 +
   22.14 +/// Shared instance of logger.
   22.15 +class Log {
   22.16 +    static let shared = Logger(subsystem: "security.pEp.MessageModel", category: "MessageModule")
   22.17 +
   22.18 +    /// Init is forbidden. Singleton...
   22.19 +    private init() {}
   22.20 +}
    23.1 --- a/MessageModel/MessageModel/Modules/Log/MMLog.swift	Fri May 03 12:19:46 2019 +0200
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,19 +0,0 @@
    23.4 -//
    23.5 -//  MMLog.swift
    23.6 -//  MessageModel
    23.7 -//
    23.8 -//  Created by Andreas Buff on 01.03.19.
    23.9 -//  Copyright © 2019 pEp Security S.A. All rights reserved.
   23.10 -//
   23.11 -
   23.12 -import pEpIOSToolbox
   23.13 -
   23.14 -//!!!: rename to "Log" after old Log has been removed
   23.15 -
   23.16 -/// Shared instance of logger.
   23.17 -class MMLog {
   23.18 -    static let shared = Logger(subsystem: "security.pEp.MessageModel", category: "MessageModule")
   23.19 -
   23.20 -    /// Init is forbidden. Singleton...
   23.21 -    private init() {}
   23.22 -}
    24.1 --- a/MessageModel/MessageModel/Modules/QueryResultsController/QueryResultsController/QueryResultsController.swift	Fri May 03 12:19:46 2019 +0200
    24.2 +++ b/MessageModel/MessageModel/Modules/QueryResultsController/QueryResultsController/QueryResultsController.swift	Mon May 20 16:30:04 2019 +0200
    24.3 @@ -35,7 +35,7 @@
    24.4  
    24.5      func getResults() throws -> [T] {
    24.6          guard let controller = frc else {
    24.7 -            Log.shared.errorAndCrash(component: #function, errorString: "no controller")
    24.8 +            Log.shared.errorAndCrash("no controller")
    24.9              throw QueryResultsController.InvalidStateError.notInitialized
   24.10          }
   24.11          guard let results = controller.fetchedObjects else {
    25.1 --- a/MessageModel/MessageModel/NetworkService/Filter/AttachmentFilter.swift	Fri May 03 12:19:46 2019 +0200
    25.2 +++ b/MessageModel/MessageModel/NetworkService/Filter/AttachmentFilter.swift	Mon May 20 16:30:04 2019 +0200
    25.3 @@ -7,11 +7,6 @@
    25.4  //
    25.5  
    25.6  public class AttachmentFilter: FilterBase {
    25.7 -    public static let unviewableMimeTypes = Set([
    25.8 -        MimeTypeUtil.contentTypeApplicationPGPKeys,
    25.9 -        "application/pgp-signature"]
   25.10 -    )
   25.11 -
   25.12      public override var predicates : [NSPredicate] {
   25.13          get {
   25.14              return [CdMessage.PredicateFactory.hasViewableAttachments()]
   25.15 @@ -26,7 +21,7 @@
   25.16  
   25.17      public override func fulfillsFilter(message: Message) -> Bool {
   25.18          let viewableAttachments = message.attachments.filter {
   25.19 -            !AttachmentFilter.unviewableMimeTypes.contains($0.mimeType.lowercased())
   25.20 +            !MimeTypeUtils.unviewableMimeTypes.contains($0.mimeType.lowercased())
   25.21          }
   25.22          return viewableAttachments.count > 0
   25.23      }
    26.1 --- a/MessageModel/MessageModel/NetworkService/IMAP/DefaultImapSyncDelegate.swift	Fri May 03 12:19:46 2019 +0200
    26.2 +++ b/MessageModel/MessageModel/NetworkService/IMAP/DefaultImapSyncDelegate.swift	Mon May 20 16:30:04 2019 +0200
    26.3 @@ -21,7 +21,7 @@
    26.4  
    26.5      class CrashingErrorHandler: ImapSyncDelegateErrorHandlerProtocol {
    26.6          func handle(error: Error) {
    26.7 -            Logger.backendLogger.errorAndCrash(
    26.8 +            Log.shared.errorAndCrash(
    26.9                  "Error occurred, but no error handler defined: %{public}@",
   26.10                  error.localizedDescription)
   26.11          }
    27.1 --- a/MessageModel/MessageModel/NetworkService/IMAP/EmailConnectInfo+BasicConnectInfo.swift	Fri May 03 12:19:46 2019 +0200
    27.2 +++ b/MessageModel/MessageModel/NetworkService/IMAP/EmailConnectInfo+BasicConnectInfo.swift	Mon May 20 16:30:04 2019 +0200
    27.3 @@ -13,13 +13,11 @@
    27.4   */
    27.5  public extension EmailConnectInfo {
    27.6      func basicConnectInfo() -> BasicConnectInfo {
    27.7 -        let token = self.accessToken
    27.8 -
    27.9          return BasicConnectInfo(
   27.10              accountEmailAddress: account.address,
   27.11              loginName: loginName,
   27.12              loginPassword: loginPassword,
   27.13 -            accessToken: token,
   27.14 +            accessToken: self.accessToken,
   27.15              networkAddress: networkAddress,
   27.16              networkPort: networkPort,
   27.17              connectionTransport: connectionTransport,
    28.1 --- a/MessageModel/MessageModel/NetworkService/IMAP/EmailConnectInfo.swift	Fri May 03 12:19:46 2019 +0200
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,141 +0,0 @@
    28.4 -//
    28.5 -//  EmailConnectInfo.swift
    28.6 -//  pEp
    28.7 -//
    28.8 -//  Created by Andreas Buff on 23.07.18.
    28.9 -//  Copyright © 2018 p≡p Security S.A. All rights reserved.
   28.10 -//
   28.11 -
   28.12 -import PantomimeFramework
   28.13 -
   28.14 -extension ConnectionTransport {
   28.15 -    public init?(fromInt: Int?) {
   28.16 -        guard let i = fromInt else {
   28.17 -            return nil
   28.18 -        }
   28.19 -        switch i {
   28.20 -        case ConnectionTransport.plain.rawValue:
   28.21 -            self = ConnectionTransport.plain
   28.22 -        case ConnectionTransport.startTLS.rawValue:
   28.23 -            self = ConnectionTransport.startTLS
   28.24 -        case ConnectionTransport.TLS.rawValue:
   28.25 -            self = ConnectionTransport.TLS
   28.26 -        default:
   28.27 -            return nil
   28.28 -        }
   28.29 -    }
   28.30 -
   28.31 -    public static func fromInteger(_ i: Int) -> ConnectionTransport {
   28.32 -        switch i {
   28.33 -        case ConnectionTransport.plain.rawValue:
   28.34 -            return ConnectionTransport.plain
   28.35 -        case ConnectionTransport.startTLS.rawValue:
   28.36 -            return ConnectionTransport.startTLS
   28.37 -        case ConnectionTransport.TLS.rawValue:
   28.38 -            return ConnectionTransport.TLS
   28.39 -        default:
   28.40 -            abort()
   28.41 -        }
   28.42 -    }
   28.43 -
   28.44 -    public func localizedString() -> String {
   28.45 -        let transport_security_text = "Transport security (ConnectionTransport)"
   28.46 -        switch self {
   28.47 -        case .plain:
   28.48 -            return NSLocalizedString("None", comment: transport_security_text)
   28.49 -        case .TLS:
   28.50 -            return NSLocalizedString("TLS", comment: transport_security_text)
   28.51 -        case .startTLS:
   28.52 -            return NSLocalizedString("StartTLS", comment: transport_security_text)
   28.53 -        }
   28.54 -    }
   28.55 -
   28.56 -    // XXX: Here material from the Model area is used: to be avoided or code-shared.
   28.57 -    public func toServerTransport() -> Server.Transport {
   28.58 -        switch self {
   28.59 -        case .plain: return Server.Transport.plain
   28.60 -        case .TLS: return Server.Transport.tls
   28.61 -        case .startTLS: return Server.Transport.startTls
   28.62 -        }
   28.63 -    }
   28.64 -}
   28.65 -
   28.66 -public enum EmailProtocol: String {
   28.67 -    case smtp = "SMTP"
   28.68 -    case imap = "IMAP"
   28.69 -
   28.70 -    public init?(emailProtocol: String) {
   28.71 -        if emailProtocol.isEqual(EmailProtocol.smtp.rawValue) {
   28.72 -            self = .smtp
   28.73 -        } else if emailProtocol.isEqual(EmailProtocol.imap.rawValue) {
   28.74 -            self = .imap
   28.75 -        } else {
   28.76 -            return nil
   28.77 -        }
   28.78 -    }
   28.79 -
   28.80 -    public init?(serverType: Server.ServerType?) {
   28.81 -        guard let st = serverType else {
   28.82 -            return nil
   28.83 -        }
   28.84 -        switch st {
   28.85 -        case .imap:
   28.86 -            self = .imap
   28.87 -        case .smtp:
   28.88 -            self = .smtp
   28.89 -        }
   28.90 -    }
   28.91 -}
   28.92 -
   28.93 -public class EmailConnectInfo: ConnectInfo {
   28.94 -    enum EmailConnectInfoError: Error {
   28.95 -        case cannotFindServerCredentials
   28.96 -    }
   28.97 -
   28.98 -    let emailProtocol: EmailProtocol?
   28.99 -    let connectionTransport: ConnectionTransport?
  28.100 -    let authMethod: AuthMethod?
  28.101 -    let trusted: Bool
  28.102 -
  28.103 -    /**
  28.104 -     There is either the `loginPassword`, or this, but there should never exist both.
  28.105 -     If non-nil, the `authMethod` is expected to be `AuthMethod.saslXoauth2`.
  28.106 -     */
  28.107 -    var accessToken: OAuth2AccessTokenProtocol? {
  28.108 -        guard authMethod == .saslXoauth2,
  28.109 -            let key = loginPasswordKeyChainKey,
  28.110 -            let token = KeyChain.serverPassword(forKey: key) else {
  28.111 -                return nil
  28.112 -        }
  28.113 -        return OAuth2AccessToken.from(base64Encoded: token) as? OAuth2AccessTokenProtocol
  28.114 -    }
  28.115 -
  28.116 -    init(account: CdAccount,
  28.117 -         server: CdServer,
  28.118 -         credentials: CdServerCredentials,
  28.119 -         loginName: String? = nil,
  28.120 -         loginPasswordKeyChainKey: String? = nil,
  28.121 -         networkAddress: String,
  28.122 -         networkPort: UInt16,
  28.123 -         networkAddressType: NetworkAddressType? = nil,
  28.124 -         networkTransportType: NetworkTransportType? = nil,
  28.125 -         emailProtocol: EmailProtocol? = nil,
  28.126 -         connectionTransport: ConnectionTransport? = nil,
  28.127 -         authMethod: AuthMethod? = nil,
  28.128 -         trusted: Bool = false) {
  28.129 -        self.emailProtocol = emailProtocol
  28.130 -        self.connectionTransport = connectionTransport
  28.131 -        self.authMethod = authMethod
  28.132 -        self.trusted = trusted
  28.133 -
  28.134 -        super.init(account: account,
  28.135 -                   server: server,
  28.136 -                   credentials: credentials,
  28.137 -                   loginName: loginName,
  28.138 -                   loginPasswordKeyChainKey: loginPasswordKeyChainKey,
  28.139 -                   networkAddress: networkAddress,
  28.140 -                   networkPort: networkPort,
  28.141 -                   networkAddressType: networkAddressType,
  28.142 -                   networkTransportType: networkTransportType)
  28.143 -    }
  28.144 -}
    29.1 --- a/MessageModel/MessageModel/NetworkService/IMAP/ImapFolderBuilder.swift	Fri May 03 12:19:46 2019 +0200
    29.2 +++ b/MessageModel/MessageModel/NetworkService/IMAP/ImapFolderBuilder.swift	Mon May 20 16:30:04 2019 +0200
    29.3 @@ -33,7 +33,7 @@
    29.4  
    29.5      open func folder(withName: String) -> CWFolder {
    29.6          if folderNameToIgnore != nil && withName == folderNameToIgnore {
    29.7 -            Logger.backendLogger.warn("ignoring folder %{public}@", withName)
    29.8 +            Log.shared.warn("ignoring folder %{public}@", withName)
    29.9              return CWFolder(name: withName)
   29.10          } else {
   29.11              if let theFolder = PersistentImapFolder(
    30.1 --- a/MessageModel/MessageModel/NetworkService/IMAP/ImapService.swift	Fri May 03 12:19:46 2019 +0200
    30.2 +++ b/MessageModel/MessageModel/NetworkService/IMAP/ImapService.swift	Mon May 20 16:30:04 2019 +0200
    30.3 @@ -95,7 +95,7 @@
    30.4                  if newValue {
    30.5                      state = .error
    30.6                  } else {
    30.7 -                    Logger.backendLogger.error("clearing hasError")
    30.8 +                    Log.shared.error("clearing hasError")
    30.9                  }
   30.10              }
   30.11          }
   30.12 @@ -272,7 +272,7 @@
   30.13  
   30.14      private func runOnDelegate(logName: String = #function, block: (ImapSyncDelegate) -> ()) {
   30.15          guard let del = delegate else  {
   30.16 -            Logger.backendLogger.warn("No delegate")
   30.17 +            Log.shared.warn("No delegate")
   30.18              return
   30.19          }
   30.20          block(del)
   30.21 @@ -404,7 +404,7 @@
   30.22              group.enter()
   30.23              token.performAction() { [weak self] error, freshToken in
   30.24                  if let err = error {
   30.25 -                    Logger.backendLogger.error("%{public}@", err.localizedDescription)
   30.26 +                    Log.shared.error("%{public}@", err.localizedDescription)
   30.27                      if let theSelf = self {
   30.28                          theSelf.runOnDelegate(logName: #function) { theDelegate in
   30.29                              theDelegate.authenticationFailed(theSelf, notification: nil)
   30.30 @@ -430,10 +430,10 @@
   30.31                  loginName, password: loginPassword, mechanism: bestAuthMethod().rawValue)
   30.32          } else {
   30.33              if connectInfo.loginPassword == nil {
   30.34 -                Logger.backendLogger.error("Want to login, but don't have a password")
   30.35 +                Log.shared.error("Want to login, but don't have a password")
   30.36              }
   30.37              if connectInfo.loginName == nil {
   30.38 -                Logger.backendLogger.error("Want to login, but don't have a login")
   30.39 +                Log.shared.error("Want to login, but don't have a login")
   30.40              }
   30.41              runOnDelegate(logName: #function) { theDelegate in
   30.42                  theDelegate.authenticationFailed(self, notification: notification)
    31.1 --- a/MessageModel/MessageModel/NetworkService/Model/PersistentImapFolder.swift	Fri May 03 12:19:46 2019 +0200
    31.2 +++ b/MessageModel/MessageModel/NetworkService/Model/PersistentImapFolder.swift	Mon May 20 16:30:04 2019 +0200
    31.3 @@ -98,7 +98,7 @@
    31.4          context.performAndWait() {
    31.5              guard let account = context.object(with: accountID)
    31.6                  as? CdAccount else {
    31.7 -                    Logger.backendLogger.error(
    31.8 +                    Log.shared.error(
    31.9                          "Given objectID is not an account: %{public}@",
   31.10                          accountID.description)
   31.11                      return
   31.12 @@ -201,7 +201,7 @@
   31.13              let uid = cwImapMessage.uid()
   31.14              removeMessage(withUID: uid)
   31.15          } else {
   31.16 -            Logger.backendLogger.log("Should remove/expunge message that is not a CWIMAPMessage")
   31.17 +            Log.shared.log("Should remove/expunge message that is not a CWIMAPMessage")
   31.18          }
   31.19      }
   31.20  
   31.21 @@ -258,7 +258,7 @@
   31.22                      Record.saveAndWait(context: privateMOC)
   31.23                  }
   31.24              } else {
   31.25 -                Logger.backendLogger.log("Could not find message by UID for expunging.")
   31.26 +                Log.shared.log("Could not find message by UID for expunging.")
   31.27              }
   31.28          }
   31.29      }
   31.30 @@ -273,13 +273,13 @@
   31.31  
   31.32      override func setUIDValidity(_ theUIDValidity: UInt) {
   31.33          guard let context = self.folder.managedObjectContext else {
   31.34 -            Logger.backendLogger.errorAndCrash("Dangling folder")
   31.35 +            Log.shared.errorAndCrash("Dangling folder")
   31.36              return
   31.37          }
   31.38          context.performAndWait() {
   31.39              let uidValidityNeverFetchedFromServer = self.folder.uidValidity == 0
   31.40              if !uidValidityNeverFetchedFromServer && self.folder.uidValidity != Int32(theUIDValidity) {
   31.41 -                Logger.backendLogger.warn(
   31.42 +                Log.shared.warn(
   31.43                      "UIValidity changed, deleting all messages. %{public}@",
   31.44                      String(describing: self.folder.name))
   31.45                  // For some reason messages are not deleted when removing it from folder
   31.46 @@ -306,7 +306,7 @@
   31.47              parentName: functionName(#function),
   31.48              accountID: accountID, message: message, messageUpdate: messageUpdate)
   31.49          let opID = unsafeBitCast(opStore, to: UnsafeRawPointer.self)
   31.50 -        Logger.backendLogger.warn("Writing message %{public}@, %{public}@ for %{public}@",
   31.51 +        Log.shared.warn("Writing message %{public}@, %{public}@ for %{public}@",
   31.52                                    message,
   31.53                                    messageUpdate,
   31.54                                    String(describing: opID))
    32.1 --- a/MessageModel/MessageModel/NetworkService/Network/ConnectInfo/EmailConnectInfo+Extension.swift	Fri May 03 12:19:46 2019 +0200
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,44 +0,0 @@
    32.4 -//
    32.5 -//  EmailConnectInfo+Extension.swift
    32.6 -//  pEpForiOS
    32.7 -//
    32.8 -//  Created by Dirk Zimmermann on 24.07.17.
    32.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   32.10 -//
   32.11 -
   32.12 -import Foundation
   32.13 -import CoreData
   32.14 -
   32.15 -import pEpIOSToolbox
   32.16 -
   32.17 -extension EmailConnectInfo {
   32.18 -
   32.19 -    func folderBy(name: String) throws -> Folder? {
   32.20 -        var cdResult: CdFolder?
   32.21 -        var error: Error?
   32.22 -        MessageModelUtil.performAndWait { [weak self] in
   32.23 -            guard let me = self else {
   32.24 -                Logger.frontendLogger.lostMySelf()
   32.25 -                return
   32.26 -            }
   32.27 -            let context = Record.Context.background
   32.28 -            guard
   32.29 -                let accountId = me.accountObjectID,
   32.30 -                let cdAccount = context.object(with: accountId) as? CdAccount else {
   32.31 -                    error = BackgroundError.CoreDataError.couldNotFindAccount(info: #function)
   32.32 -                    return
   32.33 -            }
   32.34 -            guard
   32.35 -                let cdFolder = CdFolder.by(name: name, account: cdAccount, context: context) else {
   32.36 -                    error = BackgroundError.CoreDataError.couldNotFindFolder(info: #function)
   32.37 -                    return
   32.38 -            }
   32.39 -            cdResult = cdFolder
   32.40 -        }
   32.41 -        if let error = error {
   32.42 -            throw error
   32.43 -        }
   32.44 -        return cdResult?.folder()
   32.45 -    }
   32.46 -
   32.47 -}
    33.1 --- a/MessageModel/MessageModel/NetworkService/Network/Service/AccountVerificationService/AccountVerificationService.swift	Fri May 03 12:19:46 2019 +0200
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,98 +0,0 @@
    33.4 -//
    33.5 -//  AccountVerificationService.swift
    33.6 -//  pEpForiOS
    33.7 -//
    33.8 -//  Created by Dirk Zimmermann on 24.05.17.
    33.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   33.10 -//
   33.11 -
   33.12 -import pEpIOSToolbox
   33.13 -import PantomimeFramework
   33.14 -
   33.15 -class AccountVerificationService: AccountVerificationServiceProtocol {
   33.16 -    weak var delegate: AccountVerificationServiceDelegate?
   33.17 -
   33.18 -    var runningOperations = [Account:[BaseOperation]]()
   33.19 -    let verificationQueue = DispatchQueue(
   33.20 -        label: "AccountVerificationService.verificationQueue", qos: .utility, target: nil)
   33.21 -    let backgroundQueue = OperationQueue()
   33.22 -
   33.23 -    func verify(account: Account) {
   33.24 -        verificationQueue.async {
   33.25 -            self.verifyInternal(account: account)
   33.26 -        }
   33.27 -    }
   33.28 -
   33.29 -    func removeFromRunning(account: Account) {
   33.30 -        verificationQueue.async {
   33.31 -            self.removeFromRunningInternal(account: account)
   33.32 -        }
   33.33 -    }
   33.34 -
   33.35 -    func removeFromRunningInternal(account: Account) {
   33.36 -        guard let ops = runningOperations[account] else {
   33.37 -            return
   33.38 -        }
   33.39 -        let runningOps = ops.filter() {
   33.40 -            return !$0.isFinished
   33.41 -        }
   33.42 -        if runningOps.isEmpty {
   33.43 -            runningOperations[account] = nil
   33.44 -            let errorOps = ops.filter() { return $0.hasErrors() }
   33.45 -            if let op = errorOps.first, let err = op.error {
   33.46 -                if let imapErr = err as? ImapSyncError {
   33.47 -                    delegate?.verified(account: account, service: self, result: .imapError(imapErr))
   33.48 -                } else if let smtpErr = err as? SmtpSendError {
   33.49 -                    delegate?.verified(account: account, service: self, result: .smtpError(smtpErr))
   33.50 -                }
   33.51 -            } else {
   33.52 -                delegate?.verified(account: account, service: self, result: .ok)
   33.53 -            }
   33.54 -        }
   33.55 -    }
   33.56 -
   33.57 -    func verifyInternal(account: Account) {
   33.58 -        if runningOperations[account] != nil {
   33.59 -            return
   33.60 -        }
   33.61 -        let moc = Record.Context.background
   33.62 -        moc.perform { [weak self] in
   33.63 -            guard let me = self else {
   33.64 -                Logger.backendLogger.errorAndCrash("I am lost")
   33.65 -                return
   33.66 -            }
   33.67 -
   33.68 -            guard let cdAccount = account.cdAccount() else {
   33.69 -                Logger.backendLogger.errorAndCrash("No account.cdAccount()")
   33.70 -                return
   33.71 -            }
   33.72 -
   33.73 -            guard let imapConnectInfo = cdAccount.imapConnectInfo else {
   33.74 -                me.delegate?.verified(account: account, service: me, result: .noImapConnectData)
   33.75 -                return
   33.76 -            }
   33.77 -            guard let smtpConnectInfo = cdAccount.smtpConnectInfo else {
   33.78 -                me.delegate?.verified(account: account, service: me, result: .noSmtpConnectData)
   33.79 -                return
   33.80 -            }
   33.81 -            let imapSyncData = ImapSyncData(connectInfo: imapConnectInfo)
   33.82 -            let smtpSendData = SmtpSendData(connectInfo: smtpConnectInfo)
   33.83 -            let imapVerifyOp = LoginImapOperation(
   33.84 -                parentName: #function, errorContainer: ErrorContainer(), imapSyncData: imapSyncData)
   33.85 -            imapVerifyOp.completionBlock = {[weak self] in
   33.86 -                imapVerifyOp.completionBlock = nil
   33.87 -                self?.removeFromRunning(account: account)
   33.88 -            }
   33.89 -            let smtpVerifyOp = LoginSmtpOperation(parentName: #function,
   33.90 -                                                  smtpSendData: smtpSendData,
   33.91 -                                                  errorContainer: ErrorContainer())
   33.92 -            smtpVerifyOp.completionBlock = {[weak self] in
   33.93 -                smtpVerifyOp.completionBlock = nil
   33.94 -                self?.removeFromRunning(account: account)
   33.95 -            }
   33.96 -            me.runningOperations[account] = [imapVerifyOp, smtpVerifyOp]
   33.97 -            me.backgroundQueue.addOperation(imapVerifyOp)
   33.98 -            me.backgroundQueue.addOperation(smtpVerifyOp)
   33.99 -        }
  33.100 -    }
  33.101 -}
    34.1 --- a/MessageModel/MessageModel/NetworkService/Network/Service/FetchImapFoldersService.swift	Fri May 03 12:19:46 2019 +0200
    34.2 +++ b/MessageModel/MessageModel/NetworkService/Network/Service/FetchImapFoldersService.swift	Mon May 20 16:30:04 2019 +0200
    34.3 @@ -26,7 +26,7 @@
    34.4      
    34.5      func fetchFolders(inAccount account: Account) {
    34.6          guard let cdAccount = account.cdAccount() else {
    34.7 -            Logger.backendLogger.errorAndCrash("No account.cdAccount()")
    34.8 +            Log.shared.errorAndCrash("No account.cdAccount()")
    34.9              return
   34.10          }
   34.11  
    35.1 --- a/MessageModel/MessageModel/NetworkService/Network/Service/MessageSyncService/VerificationServiceProtocol.swift	Fri May 03 12:19:46 2019 +0200
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,24 +0,0 @@
    35.4 -//
    35.5 -//  VerificationServiceProtocol.swift
    35.6 -//  pEpForiOS
    35.7 -//
    35.8 -//  Created by Dirk Zimmermann on 01.06.17.
    35.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   35.10 -//
   35.11 -
   35.12 -import Foundation
   35.13 -
   35.14 -/**
   35.15 - Message sync related actions that can be requested by the UI.
   35.16 - The purpose is to make network-related actions seem as fast as possible,
   35.17 - even with accounts that have to be polled, while still letting the backend
   35.18 - have full control over the scheduling.
   35.19 - */
   35.20 -public protocol VerificationServiceProtocol {
   35.21 -    /**
   35.22 -     Request account verification, receiving news via the delegate.
   35.23 -     Backend might start syncing the inbox as soon as the verification
   35.24 -     was successful.
   35.25 -     */
   35.26 -    func requestVerification(account: Account, delegate: AccountVerificationServiceDelegate)
   35.27 -}
    36.1 --- a/MessageModel/MessageModel/NetworkService/Network/Service/QualifyServerIsLocalOperation.swift	Fri May 03 12:19:46 2019 +0200
    36.2 +++ b/MessageModel/MessageModel/NetworkService/Network/Service/QualifyServerIsLocalOperation.swift	Mon May 20 16:30:04 2019 +0200
    36.3 @@ -107,7 +107,7 @@
    36.4                                                      UInt8(addr >> 8 & 255), UInt8(addr & 255))
    36.5                      ipAddresses.append(ip4Address)
    36.6                  } else {
    36.7 -                    Logger.backendLogger.errorAndCrash("unknown address family")
    36.8 +                    Log.shared.errorAndCrash("unknown address family")
    36.9                  }
   36.10              }
   36.11          }
    37.1 --- a/MessageModel/MessageModel/NetworkService/NetworkServiceConfig.swift	Fri May 03 12:19:46 2019 +0200
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,53 +0,0 @@
    37.4 -//
    37.5 -//  NetworkServiceConfig.swift
    37.6 -//  MessageModel
    37.7 -//
    37.8 -//  Created by Dirk Zimmermann on 22.02.19.
    37.9 -//  Copyright © 2019 pEp Security S.A. All rights reserved.
   37.10 -//
   37.11 -
   37.12 -import Foundation
   37.13 -
   37.14 -/**
   37.15 - Lets the client of this framework decide about whether an address belongs to a
   37.16 - server manually tagged by the user as trusted.
   37.17 - */
   37.18 -public protocol ManuallyTrustedServerProtocol {
   37.19 -    func isManuallyTrustedServer(address: String) -> Bool
   37.20 -}
   37.21 -
   37.22 -/**
   37.23 - Lets the client of this framework decide what the default account email address is.
   37.24 - */
   37.25 -public protocol DefaultAccountGetterProtocol {
   37.26 -    var defaultAccount: String? { get }
   37.27 -}
   37.28 -
   37.29 -/**
   37.30 - Some delegates/factories the app has to set up in order for the
   37.31 - network service/message model to be able to work properly,
   37.32 - in order to avoid a dependency on `AppSetting`s.
   37.33 - - Note: The name might be misleading, but the class was created
   37.34 - when moving the network service out of the app into the message model.
   37.35 - */
   37.36 -public class NetworkServiceConfig {
   37.37 -    /**
   37.38 -     Lets the client decide about whether an address belongs to a
   37.39 -     server manually tagged by the user as trusted.
   37.40 -     */
   37.41 -    public static var manuallyTrustedServerTagger: ManuallyTrustedServerProtocol =
   37.42 -        DefaultManuallyTrustedServer()
   37.43 -
   37.44 -    public static var defaultAccountGetter: DefaultAccountGetterProtocol =
   37.45 -        DefaultAccountGetter()
   37.46 -
   37.47 -    private class DefaultManuallyTrustedServer: ManuallyTrustedServerProtocol {
   37.48 -        func isManuallyTrustedServer(address: String) -> Bool {
   37.49 -            return false
   37.50 -        }
   37.51 -    }
   37.52 -
   37.53 -    private class DefaultAccountGetter: DefaultAccountGetterProtocol {
   37.54 -        var defaultAccount: String? = nil
   37.55 -    }
   37.56 -}
    38.1 --- a/MessageModel/MessageModel/NetworkService/NetworkServiceWorker.swift	Fri May 03 12:19:46 2019 +0200
    38.2 +++ b/MessageModel/MessageModel/NetworkService/NetworkServiceWorker.swift	Mon May 20 16:30:04 2019 +0200
    38.3 @@ -117,7 +117,7 @@
    38.4  
    38.5          workerQueue.async {[weak self] in
    38.6              guard let me = self else {
    38.7 -                Logger.backendLogger.lostMySelf()
    38.8 +                Log.shared.lostMySelf()
    38.9                  return
   38.10              }
   38.11              let observer = ObjectObserver(
   38.12 @@ -145,7 +145,7 @@
   38.13          cancelled = true
   38.14          workerQueue.async { [weak self] in
   38.15              guard let me = self else {
   38.16 -                Logger.backendLogger.lostMySelf()
   38.17 +                Log.shared.lostMySelf()
   38.18                  return
   38.19              }
   38.20              // Cancel the current sync loop ...
   38.21 @@ -241,7 +241,7 @@
   38.22                                errorContainer: ServiceErrorProtocol) -> Operation {
   38.23          let resultOp = SelfReferencingOperation() { operation in
   38.24              guard let operation = operation else {
   38.25 -                Logger.backendLogger.lostMySelf()
   38.26 +                Log.shared.lostMySelf()
   38.27                  return
   38.28              }
   38.29              if operation.isCancelled {
   38.30 @@ -252,7 +252,7 @@
   38.31              var lastOp = Operation()
   38.32              operations.append(lastOp)
   38.33  
   38.34 -            MessageModelUtil.performAndWait {
   38.35 +            Record.Context.background.performAndWait {
   38.36                  if operation.isCancelled {
   38.37                      return
   38.38                  }
   38.39 @@ -277,7 +277,7 @@
   38.40                                         errorContainer: ServiceErrorProtocol) -> Operation {
   38.41          let resultOp = SelfReferencingOperation() { operation in
   38.42              guard let operation = operation else {
   38.43 -                Logger.backendLogger.lostMySelf()
   38.44 +                Log.shared.lostMySelf()
   38.45                  return
   38.46              }
   38.47              if operation.isCancelled {
   38.48 @@ -287,7 +287,7 @@
   38.49              var operations = [Operation]()
   38.50              var lastOp = Operation()
   38.51              operations.append(lastOp)
   38.52 -            MessageModelUtil.performAndWait {
   38.53 +            Record.Context.background.performAndWait {
   38.54                  if operation.isCancelled {
   38.55                      return
   38.56                  }
   38.57 @@ -389,7 +389,7 @@
   38.58                                         onlySyncChangesTriggeredByUser: Bool) -> Operation {
   38.59          let resultOp = SelfReferencingOperation() { [weak self] operation in
   38.60              guard let me = self, let operation = operation else {
   38.61 -                Logger.backendLogger.lostMySelf()
   38.62 +                Log.shared.lostMySelf()
   38.63                  return
   38.64              }
   38.65              if operation.isCancelled {
   38.66 @@ -399,7 +399,7 @@
   38.67              var operations = [Operation]()
   38.68              var lastOp = Operation()
   38.69              operations.append(lastOp)
   38.70 -            MessageModelUtil.performAndWait {
   38.71 +            Record.Context.background.performAndWait {
   38.72                  if operation.isCancelled {
   38.73                      return
   38.74                  }
   38.75 @@ -561,7 +561,7 @@
   38.76                          let me = self,
   38.77                          let decryptOp = opDecrypt,
   38.78                          let operation = operation else {
   38.79 -                            Logger.backendLogger.lostMySelf()
   38.80 +                            Log.shared.lostMySelf()
   38.81                              return
   38.82                      }
   38.83                      if operation.isCancelled {
   38.84 @@ -663,7 +663,7 @@
   38.85          }
   38.86          workerQueue.async { [weak self] in
   38.87              guard let me = self else {
   38.88 -                Logger.backendLogger.lostMySelf()
   38.89 +                Log.shared.lostMySelf()
   38.90                  return
   38.91              }
   38.92              if me.cancelled {
    39.1 --- a/MessageModel/MessageModel/NetworkService/Operations/AppendMailsOperation.swift	Fri May 03 12:19:46 2019 +0200
    39.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/AppendMailsOperation.swift	Mon May 20 16:30:04 2019 +0200
    39.3 @@ -20,7 +20,8 @@
    39.4          case unencryptedForTrustedServer
    39.5      }
    39.6      private var encryptMode: EncryptMode {
    39.7 -        return imapSyncData.connectInfo.trusted ? .unencryptedForTrustedServer : .forSelf
    39.8 +        let isTrusted = imapSyncData.connectInfo.isTrusted(context: privateMOC)
    39.9 +        return isTrusted ? .unencryptedForTrustedServer : .forSelf
   39.10      }
   39.11      private var syncDelegate: AppendMailsSyncDelegate?
   39.12  
   39.13 @@ -51,7 +52,7 @@
   39.14          var result: (PEPMessageDict, PEPIdentity, NSManagedObjectID)? = nil
   39.15          privateMOC.performAndWait { [weak self] in
   39.16              guard let me = self else {
   39.17 -                Logger.backendLogger.lostMySelf()
   39.18 +                Log.shared.lostMySelf()
   39.19                  return
   39.20              }
   39.21              guard
   39.22 @@ -59,7 +60,7 @@
   39.23                  let account = privateMOC.object(with: accountId) as? CdAccount,
   39.24                  let address = account.identity?.address
   39.25                  else {
   39.26 -                    Logger.backendLogger.errorAndCrash("Missing data")
   39.27 +                    Log.shared.errorAndCrash("Missing data")
   39.28                      result = nil
   39.29                      return
   39.30              }
   39.31 @@ -78,14 +79,14 @@
   39.32          if let msgID = lastHandledMessageObjectID {
   39.33              privateMOC.performAndWait { [weak self] in
   39.34                  guard let me = self else {
   39.35 -                    Logger.backendLogger.lostMySelf()
   39.36 +                    Log.shared.lostMySelf()
   39.37                      return
   39.38                  }
   39.39                  if let obj = me.privateMOC.object(with: msgID) as? CdMessage {
   39.40                      me.privateMOC.delete(obj)
   39.41                      me.privateMOC.saveAndLogErrors()
   39.42                  } else {
   39.43 -                    Logger.backendLogger.errorAndCrash("Message disappeared")
   39.44 +                    Log.shared.errorAndCrash("Message disappeared")
   39.45                      me.handleError(BackgroundError.GeneralError.invalidParameter(info: #function),
   39.46                                     message: "Cannot find message just stored.")
   39.47                      return
   39.48 @@ -101,7 +102,7 @@
   39.49              cwFolder.setStore(sync.imapStore)
   39.50          }
   39.51          guard let rawData = pantMail.dataValue() else {
   39.52 -            Logger.backendLogger.errorAndCrash("No data")
   39.53 +            Log.shared.errorAndCrash("No data")
   39.54              markAsFinished()
   39.55              return
   39.56          }
   39.57 @@ -144,7 +145,7 @@
   39.58                  let session = PEPSession()
   39.59                  let (_, encMsg) = try encrypt(session: session, pEpMessageDict: msg, forSelf: ident)
   39.60                  guard let msgDict = encMsg as? PEPMessageDict else {
   39.61 -                    Logger.backendLogger.errorAndCrash("Error casting")
   39.62 +                    Log.shared.errorAndCrash("Error casting")
   39.63                      handleError(BackgroundError.GeneralError.illegalState(info: "Eror casting"),
   39.64                                  message: "Error casting")
   39.65                      return
   39.66 @@ -168,7 +169,7 @@
   39.67              guard
   39.68                  let accountId = connectInfo.accountObjectID,
   39.69                  let cdAccount = privateMOC.object(with: accountId) as? CdAccount else {
   39.70 -                    Logger.backendLogger.errorAndCrash("No account")
   39.71 +                    Log.shared.errorAndCrash("No account")
   39.72                      return
   39.73              }
   39.74              let appendMessages = CdMessage.allMessagesMarkedForAppend(inAccount: cdAccount)
    40.1 --- a/MessageModel/MessageModel/NetworkService/Operations/BaseOperation.swift	Fri May 03 12:19:46 2019 +0200
    40.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/BaseOperation.swift	Mon May 20 16:30:04 2019 +0200
    40.3 @@ -53,6 +53,6 @@
    40.4      }
    40.5  
    40.6      func logSelf(functionName: String) {
    40.7 -        Logger.backendLogger.log("%{public}@: %{public}@", comp, self)
    40.8 +        Log.shared.log("%{public}@: %{public}@", comp, self)
    40.9      }
   40.10  }
    41.1 --- a/MessageModel/MessageModel/NetworkService/Operations/ConcurrentBaseOperation.swift	Fri May 03 12:19:46 2019 +0200
    41.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/ConcurrentBaseOperation.swift	Mon May 20 16:30:04 2019 +0200
    41.3 @@ -84,7 +84,8 @@
    41.4      }
    41.5  
    41.6      func handleIlligalStateErrorAndFinish(component: String = #function, hint: String? = nil) {
    41.7 -        Log.shared.errorAndCrash(component: #function, errorString: hint ?? "")
    41.8 +        let error = hint ?? ""
    41.9 +        Log.shared.errorAndCrash("%@", error)
   41.10          handleError(
   41.11              BackgroundError.GeneralError.illegalState(info: component + " - " + (hint ?? "")))
   41.12      }
   41.13 @@ -92,9 +93,9 @@
   41.14      public func handleError(_ error: Error, message: String? = nil) {
   41.15          addError(error)
   41.16          if let theMessage = message {
   41.17 -            Logger.backendLogger.error("%{public}@ %{public}@", error.localizedDescription, theMessage)
   41.18 +            Log.shared.error("%{public}@ %{public}@", error.localizedDescription, theMessage)
   41.19          } else {
   41.20 -            Logger.backendLogger.error("%{public}@ %{public}@", error.localizedDescription)
   41.21 +            Log.shared.error("%{public}@ %{public}@", error.localizedDescription)
   41.22          }
   41.23          cancel()
   41.24      }
    42.1 --- a/MessageModel/MessageModel/NetworkService/Operations/CreateRequiredFoldersOperation.swift	Fri May 03 12:19:46 2019 +0200
    42.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/CreateRequiredFoldersOperation.swift	Mon May 20 16:30:04 2019 +0200
    42.3 @@ -45,7 +45,7 @@
    42.4          }
    42.5          privateMOC.perform { [weak self] in
    42.6              guard let me = self else {
    42.7 -                Logger.backendLogger.lostMySelf()
    42.8 +                Log.shared.lostMySelf()
    42.9                  return
   42.10              }
   42.11              me.process()
   42.12 @@ -93,7 +93,7 @@
   42.13          if let lastFolder = currentAttempt.folderToCreate {
   42.14              privateMOC.performAndWait { [weak self] in
   42.15                  guard let me = self else {
   42.16 -                    Logger.backendLogger.lostMySelf()
   42.17 +                    Log.shared.lostMySelf()
   42.18                      return
   42.19                  }
   42.20                  me.createLocal(folderToCreate: lastFolder, context: me.privateMOC)
   42.21 @@ -161,7 +161,7 @@
   42.22  class CreateRequiredFoldersSyncDelegate: DefaultImapSyncDelegate {
   42.23      public override func folderCreateCompleted(_ sync: ImapSync, notification: Notification?) {
   42.24          guard let op = errorHandler as? CreateRequiredFoldersOperation else {
   42.25 -            Logger.backendLogger.errorAndCrash("Sorry, wrong number.")
   42.26 +            Log.shared.errorAndCrash("Sorry, wrong number.")
   42.27              return
   42.28          }
   42.29          op.numberOfFoldersCreated += 1
   42.30 @@ -170,7 +170,7 @@
   42.31  
   42.32      public override func folderCreateFailed(_ sync: ImapSync, notification: Notification?) {
   42.33          guard let op = errorHandler as? CreateRequiredFoldersOperation else {
   42.34 -            Logger.backendLogger.errorAndCrash("Sorry, wrong number.")
   42.35 +            Log.shared.errorAndCrash("Sorry, wrong number.")
   42.36              return
   42.37          }
   42.38          op.createFolderAgain(potentialError: ImapSyncError.illegalState(#function))
    43.1 --- a/MessageModel/MessageModel/NetworkService/Operations/DecryptMessageOperation.swift	Fri May 03 12:19:46 2019 +0200
    43.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/DecryptMessageOperation.swift	Mon May 20 16:30:04 2019 +0200
    43.3 @@ -88,7 +88,7 @@
    43.4              delegate?.decryptMessageOperation(sender: self, didDecryptMessageWithResult: result)
    43.5  
    43.6          } catch {
    43.7 -            Logger.backendLogger.errorAndCrash("Error decrypting: %{public}@",
    43.8 +            Log.shared.errorAndCrash("Error decrypting: %{public}@",
    43.9                                                 error.localizedDescription)
   43.10              delegate?.decryptMessageOperation(sender: self, failed: error)
   43.11          }
    44.1 --- a/MessageModel/MessageModel/NetworkService/Operations/DecryptMessagesOperation.swift	Fri May 03 12:19:46 2019 +0200
    44.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/DecryptMessagesOperation.swift	Mon May 20 16:30:04 2019 +0200
    44.3 @@ -31,7 +31,7 @@
    44.4      private func setupMessagesToDecrypt() {
    44.5          privateMOC.performAndWait {[weak self] in
    44.6              guard let me = self else {
    44.7 -                Logger.backendLogger.lostMySelf()
    44.8 +                Log.shared.lostMySelf()
    44.9                  return
   44.10              }
   44.11              guard let cdMessages = CdMessage.all(
   44.12 @@ -71,7 +71,7 @@
   44.13  
   44.14          privateMOC.perform { [weak self] in
   44.15              guard let me = self else {
   44.16 -                Logger.backendLogger.lostMySelf()
   44.17 +                Log.shared.lostMySelf()
   44.18                  return
   44.19              }
   44.20              if me.isCancelled {
   44.21 @@ -104,7 +104,7 @@
   44.22                                           keys: NSArray?) {
   44.23          privateMOC.performAndWait {[weak self] in
   44.24              guard let me = self else {
   44.25 -                Logger.backendLogger.lostMySelf()
   44.26 +                Log.shared.lostMySelf()
   44.27                  return
   44.28              }
   44.29              let theKeys = Array(keys ?? NSArray()) as? [String] ?? []
   44.30 @@ -147,7 +147,7 @@
   44.31          guard
   44.32              let uuid = pEpDecryptedMessage["id"] as? String,
   44.33              let parentFolder = cdMessage.parent  else {
   44.34 -                Log.shared.errorAndCrash(component: #function, errorString:"Problem")
   44.35 +                Log.shared.errorAndCrash("No uuid or no parentFolder")
   44.36                  return
   44.37          }
   44.38  
   44.39 @@ -167,7 +167,7 @@
   44.40          cdMessage.underAttack = rating.isUnderAttack()
   44.41          guard let decrypted = pEpDecryptedMessage as? PEPMessageDict else {
   44.42  
   44.43 -                Logger.backendLogger.errorAndCrash(
   44.44 +                Log.shared.errorAndCrash(
   44.45                      "Should update message with rating %d, but nil message",
   44.46                      rating.rawValue)
   44.47                  return
   44.48 @@ -203,7 +203,6 @@
   44.49              let needsReUpload = try handleReUploadIfRequired(cdMessage: cdMessage, rating: rating)
   44.50              if needsReUpload {
   44.51                  didMarkMessagesForReUpload = true
   44.52 -                Record.saveAndWait()
   44.53                  privateMOC.saveAndLogErrors()
   44.54                  // Don't notify. Delegate will be notified after the re-uploaded message is fetched.
   44.55              } else {
   44.56 @@ -232,11 +231,12 @@
   44.57                                 rating: PEPRating) {
   44.58          cdMessage.update(pEpMessageDict: pEpMessageDict, rating: rating)
   44.59          cdMessage.updateKeyList(keys: keys)
   44.60 +        privateMOC.saveAndLogErrors()
   44.61      }
   44.62  
   44.63      private func notifyDelegate(messageUpdated cdMessage: CdMessage) {
   44.64          guard let message = cdMessage.message() else {
   44.65 -            Logger.backendLogger.errorAndCrash("Error converting CDMesage")
   44.66 +            Log.shared.errorAndCrash("Error converting CDMesage")
   44.67              return
   44.68          }
   44.69          MessageModelConfig.messageFolderDelegate?.didCreate(message: message)
   44.70 @@ -249,7 +249,7 @@
   44.71          guard
   44.72              let decrypted = result.pEpDecryptedMessage,
   44.73              let currentlyProcessedMessage = currentlyProcessedMessage else {
   44.74 -                Logger.backendLogger.errorAndCrash("Invalid state")
   44.75 +                Log.shared.errorAndCrash("Invalid state")
   44.76                  handleError(BackgroundError.GeneralError.illegalState(info:
   44.77                      "Error handling decryption result"))
   44.78                  return
   44.79 @@ -277,7 +277,7 @@
   44.80              cdMessage.wasAlreadyUnencrypted { // If the message was not encrypted, there is no reason to re-upload it.
   44.81              return false
   44.82          }   
   44.83 -        let messageCopyForReupload = cdMessage.clone()
   44.84 +        let messageCopyForReupload = cdMessage.cloneWithZeroUID()
   44.85          setOriginalRatingHeader(rating: rating, toMessage: messageCopyForReupload)
   44.86          cdMessage.imapMarkDeleted()
   44.87  
    45.1 --- a/MessageModel/MessageModel/NetworkService/Operations/DeleteFolderOperation.swift	Fri May 03 12:19:46 2019 +0200
    45.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/DeleteFolderOperation.swift	Mon May 20 16:30:04 2019 +0200
    45.3 @@ -33,7 +33,7 @@
    45.4  
    45.5          privateMOC.perform() { [weak self] in
    45.6              guard let me = self else {
    45.7 -                Logger.backendLogger.lostMySelf()
    45.8 +                Log.shared.lostMySelf()
    45.9                  return
   45.10              }
   45.11              me.account = me.privateMOC.object(with: me.accountID) as? CdAccount
   45.12 @@ -51,7 +51,7 @@
   45.13      func deleteLocalFolderAndFinish() {
   45.14          privateMOC.perform { [weak self] in
   45.15              guard let me = self else {
   45.16 -                Logger.backendLogger.lostMySelf()
   45.17 +                Log.shared.lostMySelf()
   45.18                  return
   45.19              }
   45.20              if let folder = CdFolder.by(name: me.folderName, account: me.account) {
   45.21 @@ -64,7 +64,7 @@
   45.22  
   45.23      func handleBadResponse(sync: ImapSync, response: String?) {
   45.24          let msg = response ?? "Bad Response"
   45.25 -        Logger.backendLogger.error("The folder could not be deleted: %{public}@", msg)
   45.26 +        Log.shared.error("The folder could not be deleted: %{public}@", msg)
   45.27          self.markAsFinished()
   45.28      }
   45.29  
    46.1 --- a/MessageModel/MessageModel/NetworkService/Operations/EncryptAndSendOperation.swift	Fri May 03 12:19:46 2019 +0200
    46.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/EncryptAndSendOperation.swift	Mon May 20 16:30:04 2019 +0200
    46.3 @@ -57,7 +57,7 @@
    46.4          var outgoingMsgs = [CdMessage]()
    46.5          context.performAndWait {
    46.6              guard let cdAccount = context.object(with: cdAccountObjectId) as? CdAccount else {
    46.7 -                Logger.backendLogger.errorAndCrash(
    46.8 +                Log.shared.errorAndCrash(
    46.9                      "No NSManagedObject for NSManagedObjectID")
   46.10                  outgoingMsgs = []
   46.11                  return
   46.12 @@ -115,7 +115,7 @@
   46.13              let sentFolder = CdFolder.by(folderType: .sent, account: cdAccount),
   46.14              let message = MessageModelObjectUtils().getMessage(fromCdMessage: cdMessage)
   46.15              else {
   46.16 -                Logger.backendLogger.errorAndCrash("Problem moving last message")
   46.17 +                Log.shared.errorAndCrash("Problem moving last message")
   46.18                  return
   46.19          }
   46.20          let rating = message.outgoingMessageRating().rawValue
   46.21 @@ -128,7 +128,7 @@
   46.22  
   46.23          cdMessage.createFakeMessageAndNotify()
   46.24  
   46.25 -        Logger.backendLogger.log(
   46.26 +        Log.shared.log(
   46.27              "Sent message with messageID %@",
   46.28              String(describing: cdMessage.messageID))
   46.29      }
   46.30 @@ -148,7 +148,7 @@
   46.31          let moc = privateMOC
   46.32          moc.perform { [weak self] in
   46.33              guard let me = self else {
   46.34 -                Logger.backendLogger.lostMySelf()
   46.35 +                Log.shared.lostMySelf()
   46.36                  return
   46.37              }
   46.38              me.moveLastMessageToSentFolder(context: moc)
   46.39 @@ -174,8 +174,7 @@
   46.40                      pEpMessageDict: msg, encryptionFormat: protected ? .PEP : .none)
   46.41                  guard
   46.42                      let encrypted = encryptedMessageToSend?.mutableCopy() as? PEPMessageDict else {
   46.43 -                    Log.shared.errorAndCrash(component: #function,
   46.44 -                                             errorString: "Could not encrypt but did not throw.")
   46.45 +                    Log.shared.errorAndCrash("Could not encrypt but did not throw.")
   46.46                       handleError(BackgroundError.PepError.encryptionError(info:
   46.47                          "Could not encrypt but did not throw."))
   46.48                      return
   46.49 @@ -194,7 +193,7 @@
   46.50                                           inContext moc: NSManagedObjectContext) {
   46.51          guard
   46.52              let unencryptedCdMessage = privateMOC.object(with: objId) as? CdMessage else {
   46.53 -            Logger.backendLogger.errorAndCrash("No message")
   46.54 +            Log.shared.errorAndCrash("No message")
   46.55              return
   46.56          }
   46.57  
   46.58 @@ -293,7 +292,7 @@
   46.59                  if let newValue = newHeaders as? Value {
   46.60                      self[kPepOptFields] = newValue
   46.61                  } else {
   46.62 -                    Logger.backendLogger.errorAndCrash("Can't cast to `Value`")
   46.63 +                    Log.shared.errorAndCrash("Can't cast to `Value`")
   46.64                  }
   46.65              }
   46.66          }
    47.1 --- a/MessageModel/MessageModel/NetworkService/Operations/FetchNumberOfNewMailsOperation.swift	Fri May 03 12:19:46 2019 +0200
    47.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/FetchNumberOfNewMailsOperation.swift	Mon May 20 16:30:04 2019 +0200
    47.3 @@ -39,7 +39,7 @@
    47.4  
    47.5          privateMOC.perform() { [weak self] in
    47.6              guard let me = self else {
    47.7 -                Logger.backendLogger.lostMySelf()
    47.8 +                Log.shared.lostMySelf()
    47.9                  return
   47.10              }
   47.11              me.process()
   47.12 @@ -108,7 +108,7 @@
   47.13                  self.fetchUids(sync)
   47.14              }
   47.15          } else {
   47.16 -            Logger.backendLogger.errorAndCrash("No sync")
   47.17 +            Log.shared.errorAndCrash("No sync")
   47.18              markAsFinished()
   47.19          }
   47.20      }
   47.21 @@ -140,7 +140,7 @@
   47.22              return uids
   47.23          }
   47.24          guard let cdFolderToOpen = cdFolder() else {
   47.25 -            Logger.backendLogger.errorAndCrash("No folder")
   47.26 +            Log.shared.errorAndCrash("No folder")
   47.27              return nil
   47.28          }
   47.29          guard let theOneAndOnlyUid = uids?.first else {
    48.1 --- a/MessageModel/MessageModel/NetworkService/Operations/FixAttachmentsOperation.swift	Fri May 03 12:19:46 2019 +0200
    48.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/FixAttachmentsOperation.swift	Mon May 20 16:30:04 2019 +0200
    48.3 @@ -81,7 +81,7 @@
    48.4                          }
    48.5                      }
    48.6                  } else {
    48.7 -                    Logger.backendLogger.errorAndCrash("CdAttachment with invalid URL")
    48.8 +                    Log.shared.errorAndCrash("CdAttachment with invalid URL")
    48.9                      openFetchCount -= 1
   48.10                  }
   48.11              }
   48.12 @@ -96,7 +96,7 @@
   48.13          let cdInvalidAttachments = CdAttachment.all(predicate: p, orderedBy: nil, in: context)
   48.14              as? [CdAttachment] ?? []
   48.15          if cdInvalidAttachments.count > 0 {
   48.16 -            Logger.backendLogger.error("Still %d invalid attachments",
   48.17 +            Log.shared.error("Still %d invalid attachments",
   48.18                                         cdInvalidAttachments.count)
   48.19          }
   48.20      }
   48.21 @@ -120,7 +120,7 @@
   48.22                  block(data)
   48.23                  return
   48.24              } catch let err {
   48.25 -                Logger.backendLogger.error("%@", err.localizedDescription)
   48.26 +                Log.shared.error("%@", err.localizedDescription)
   48.27              }
   48.28              let assets = PHAsset.fetchAssets(withALAssetURLs: [theURL], options: nil)
   48.29              if let theAsset = assets.firstObject {
    49.1 --- a/MessageModel/MessageModel/NetworkService/Operations/FolderInfoOperation.swift	Fri May 03 12:19:46 2019 +0200
    49.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/FolderInfoOperation.swift	Mon May 20 16:30:04 2019 +0200
    49.3 @@ -51,7 +51,7 @@
    49.4                  connectInfo: ConnectInfo,
    49.5                  folderName: String) {
    49.6          guard let accountId = connectInfo.accountObjectID else {
    49.7 -            Logger.backendLogger.errorAndCrash("No CdAccound ID")
    49.8 +            Log.shared.errorAndCrash("No CdAccound ID")
    49.9              return nil
   49.10          }
   49.11          self.accountObjectID = accountId
    50.1 --- a/MessageModel/MessageModel/NetworkService/Operations/ImapSyncOperation.swift	Fri May 03 12:19:46 2019 +0200
    50.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/ImapSyncOperation.swift	Mon May 20 16:30:04 2019 +0200
    50.3 @@ -45,7 +45,7 @@
    50.4  
    50.5  extension ImapSyncOperation: ImapSyncDelegateErrorHandlerProtocol {
    50.6      public func handle(error: Error) {
    50.7 -        Logger.backendLogger.error("%{public}@", error.localizedDescription)
    50.8 +        Log.shared.error("%{public}@", error.localizedDescription)
    50.9          addIMAPError(error)
   50.10          markAsFinished()
   50.11      }
    51.1 --- a/MessageModel/MessageModel/NetworkService/Operations/LimitedOperationQueue.swift	Fri May 03 12:19:46 2019 +0200
    51.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/LimitedOperationQueue.swift	Mon May 20 16:30:04 2019 +0200
    51.3 @@ -25,7 +25,7 @@
    51.4      open override func addOperation(_ op: Operation) {
    51.5          workerQueue.async { [weak self] in
    51.6              guard let me = self else {
    51.7 -                Logger.backendLogger.lostMySelf()
    51.8 +                Log.shared.lostMySelf()
    51.9                  return
   51.10              }
   51.11              if me.operationCount < 2 {
    52.1 --- a/MessageModel/MessageModel/NetworkService/Operations/MoveToFolderOperation.swift	Fri May 03 12:19:46 2019 +0200
    52.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/MoveToFolderOperation.swift	Mon May 20 16:30:04 2019 +0200
    52.3 @@ -48,7 +48,7 @@
    52.4          var result: CdMessage? = nil
    52.5          privateMOC.perform { [weak self] in
    52.6              guard let me = self else {
    52.7 -                Logger.backendLogger.lostMySelf()
    52.8 +                Log.shared.lostMySelf()
    52.9                  return
   52.10              }
   52.11  
   52.12 @@ -71,7 +71,7 @@
   52.13          guard let toDelete = lastProcessedMessage else {
   52.14              return
   52.15          }
   52.16 -        MessageModelUtil.performAndWait {
   52.17 +        Record.Context.background.performAndWait {
   52.18              toDelete.delete()
   52.19          }
   52.20          lastProcessedMessage = nil
   52.21 @@ -107,9 +107,9 @@
   52.22              waitForBackgroundTasksToFinish()
   52.23              return
   52.24          }
   52.25 -        MessageModelUtil.perform { [weak self] in
   52.26 +        Record.Context.background.perform { [weak self] in
   52.27              guard let me = self else {
   52.28 -                Logger.backendLogger.lostMySelf()
   52.29 +                Log.shared.lostMySelf()
   52.30                  return
   52.31              }
   52.32              guard !me.isCancelled else {
   52.33 @@ -131,7 +131,7 @@
   52.34                  return
   52.35              }
   52.36              if message.parent == message.targetFolder {
   52.37 -                Logger.backendLogger.errorAndCrash("I wounder why we are here then.")
   52.38 +                Log.shared.errorAndCrash("I wounder why we are here then.")
   52.39                  me.handleNextMessage()
   52.40                  return
   52.41              }
   52.42 @@ -185,11 +185,11 @@
   52.43      static func foldersContainingMarkedForMoveToFolder(
   52.44          connectInfo: EmailConnectInfo) -> [CdFolder] {
   52.45          var result = [CdFolder]()
   52.46 -        MessageModelUtil.performAndWait {
   52.47 +        Record.Context.background.performAndWait {
   52.48              guard
   52.49                  let accountId = connectInfo.accountObjectID,
   52.50                  let cdAccount = Record.Context.background.object(with: accountId) as? CdAccount else {
   52.51 -                    Logger.backendLogger.errorAndCrash("No account")
   52.52 +                    Log.shared.errorAndCrash("No account")
   52.53                      return
   52.54              }
   52.55              let allUidMoveMessages = CdMessage.allMessagesMarkedForMoveToFolder(
   52.56 @@ -208,7 +208,7 @@
   52.57  
   52.58      override func folderOpenCompleted(_ sync: ImapSync, notification: Notification?) {
   52.59          guard let handler = errorHandler as? MoveToFolderOperation else {
   52.60 -            Logger.backendLogger.errorAndCrash("No handler")
   52.61 +            Log.shared.errorAndCrash("No handler")
   52.62              return
   52.63          }
   52.64          handler.handleNextMessage()
   52.65 @@ -216,7 +216,7 @@
   52.66  
   52.67      override func messageUidMoveCompleted(_ sync: ImapSync, notification: Notification?) {
   52.68          guard let handler = errorHandler as? MoveToFolderOperation else {
   52.69 -            Logger.backendLogger.errorAndCrash("No handler")
   52.70 +            Log.shared.errorAndCrash("No handler")
   52.71              return
   52.72          }
   52.73          handler.handleNextMessage()
   52.74 @@ -224,7 +224,7 @@
   52.75  
   52.76      override func messagesCopyCompleted(_ sync: ImapSync, notification: Notification?) {
   52.77          guard let handler = errorHandler as? MoveToFolderOperation else {
   52.78 -            Logger.backendLogger.errorAndCrash("No handler")
   52.79 +            Log.shared.errorAndCrash("No handler")
   52.80              return
   52.81          }
   52.82          handler.handleMessageCopyCompleted()
   52.83 @@ -246,7 +246,7 @@
   52.84  
   52.85      override func messageUidMoveFailed(_ sync: ImapSync, notification: Notification?) {
   52.86          guard let handler = errorHandler as? MoveToFolderOperation else {
   52.87 -            Logger.backendLogger.errorAndCrash("No handler")
   52.88 +            Log.shared.errorAndCrash("No handler")
   52.89              return
   52.90          }
   52.91          // UID MOVE failed. We assume the server does not support it and use UID COPY as
   52.92 @@ -262,7 +262,7 @@
   52.93  
   52.94      private func handle(error: Error, on errorHandler: ImapSyncDelegateErrorHandlerProtocol?) {
   52.95          guard let handler = errorHandler as? MoveToFolderOperation else {
   52.96 -            Logger.backendLogger.errorAndCrash("Wrong delegate called")
   52.97 +            Log.shared.errorAndCrash("Wrong delegate called")
   52.98              return
   52.99          }
  52.100          handler.handleError(error)
    53.1 --- a/MessageModel/MessageModel/NetworkService/Operations/MySelfOperation.swift	Fri May 03 12:19:46 2019 +0200
    53.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/MySelfOperation.swift	Mon May 20 16:30:04 2019 +0200
    53.3 @@ -59,7 +59,7 @@
    53.4              taskName: MySelfOperation.taskNameSubOperation)
    53.5              let session = PEPSession()
    53.6              if pEpIdent.userID != CdIdentity.pEpOwnUserID {
    53.7 -                Logger.backendLogger.errorAndCrash(
    53.8 +                Log.shared.errorAndCrash(
    53.9                      "We are about to call mySelf() on a identity with userID other than pEpOwnUserID.")
   53.10              }
   53.11              do {
    54.1 --- a/MessageModel/MessageModel/NetworkService/Operations/StorePrefetchedMailOperation.swift	Fri May 03 12:19:46 2019 +0200
    54.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/StorePrefetchedMailOperation.swift	Mon May 20 16:30:04 2019 +0200
    54.3 @@ -56,7 +56,7 @@
    54.4              }
    54.5              context.saveAndLogErrors()
    54.6          } else {
    54.7 -            Logger.backendLogger.log(
    54.8 +            Log.shared.log(
    54.9                  "We could not store the message. This can happen if the belonging account just has been deleted.")
   54.10              self.addError(BackgroundError.CoreDataError.couldNotStoreMessage(info: #function))
   54.11          }
    55.1 --- a/MessageModel/MessageModel/NetworkService/Operations/SyncFlagsToServerOperation.swift	Fri May 03 12:19:46 2019 +0200
    55.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/SyncFlagsToServerOperation.swift	Mon May 20 16:30:04 2019 +0200
    55.3 @@ -62,7 +62,7 @@
    55.4  
    55.5      func startSync() {
    55.6          guard let folderName = folderName else {
    55.7 -            Logger.backendLogger.errorAndCrash("No folder name")
    55.8 +            Log.shared.errorAndCrash("No folder name")
    55.9              waitForBackgroundTasksToFinish()
   55.10              return
   55.11          }
   55.12 @@ -103,7 +103,7 @@
   55.13      func syncNextMessage() {
   55.14          let op = BlockOperation() { [weak self] in
   55.15              guard let me = self else {
   55.16 -                Logger.backendLogger.lostMySelf()
   55.17 +                Log.shared.lostMySelf()
   55.18                  return
   55.19              }
   55.20  
   55.21 @@ -144,7 +144,7 @@
   55.22  
   55.23      private func updateFlags(to mode:UpdateFlagsMode) {
   55.24          guard let message = currentlyProcessedMessage else {
   55.25 -            Logger.backendLogger.errorAndCrash("No message")
   55.26 +            Log.shared.errorAndCrash("No message")
   55.27              syncNextMessage()
   55.28              return
   55.29          }
   55.30 @@ -167,7 +167,7 @@
   55.31                                                    info: info,
   55.32                                                    string: string)
   55.33              } else {
   55.34 -                Logger.backendLogger.errorAndCrash("No IMAP store command")
   55.35 +                Log.shared.errorAndCrash("No IMAP store command")
   55.36              }
   55.37          } else if mode == .add && currentMessageNeedSyncRemoveFlagsToServer() {
   55.38              updateFlags(to: .remove)
   55.39 @@ -181,7 +181,7 @@
   55.40      func messageStoreCompleted(_ sync: ImapSync, notification: Notification?) {
   55.41          privateMOC.performAndWait { [weak self] in
   55.42              guard let me = self else {
   55.43 -                Logger.backendLogger.lostMySelf()
   55.44 +                Log.shared.lostMySelf()
   55.45                  return
   55.46              }
   55.47              // flags to add have been synced, but we might need to sync flags to remove also before
   55.48 @@ -196,7 +196,7 @@
   55.49              }
   55.50              me.storeMessages(notification: n) { [weak self] in
   55.51                  guard let me = self else {
   55.52 -                    Logger.backendLogger.lostMySelf()
   55.53 +                    Log.shared.lostMySelf()
   55.54                      return
   55.55                  }
   55.56                  me.syncNextMessage()
    56.1 --- a/MessageModel/MessageModel/NetworkService/Operations/SyncFoldersFromServerOperation.swift	Fri May 03 12:19:46 2019 +0200
    56.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/SyncFoldersFromServerOperation.swift	Mon May 20 16:30:04 2019 +0200
    56.3 @@ -74,7 +74,7 @@
    56.4              // Check if the local folder list is fairly complete
    56.5              privateMOC.perform() { [weak self] in
    56.6                  guard let me = self else {
    56.7 -                    Logger.backendLogger.lostMySelf()
    56.8 +                    Log.shared.lostMySelf()
    56.9                      return
   56.10                  }
   56.11                  guard
   56.12 @@ -131,7 +131,7 @@
   56.13      private func deleteLocalFoldersThatDoNotExistOnServerAnyMore() {
   56.14          privateMOC.performAndWait { [weak self] in
   56.15              guard let me = self else {
   56.16 -                Logger.backendLogger.lostMySelf()
   56.17 +                Log.shared.lostMySelf()
   56.18                  return
   56.19              }
   56.20              // Get all local folders that represent a remote mailbox
    57.1 --- a/MessageModel/MessageModel/NetworkService/Operations/SyncMessagesOperation.swift	Fri May 03 12:19:46 2019 +0200
    57.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/SyncMessagesOperation.swift	Mon May 20 16:30:04 2019 +0200
    57.3 @@ -89,7 +89,7 @@
    57.4          self.imapSyncData.sync?.folderBuilder = folderBuilder
    57.5  
    57.6          guard let sync = self.imapSyncData.sync else {
    57.7 -            Logger.backendLogger.errorAndCrash("No sync")
    57.8 +            Log.shared.errorAndCrash("No sync")
    57.9              handle(error: BackgroundError.GeneralError.illegalState(info: "No sync"))
   57.10              return
   57.11          }
   57.12 @@ -102,7 +102,7 @@
   57.13  
   57.14      private func resetUidCache() {
   57.15          guard let sync = self.imapSyncData.sync else {
   57.16 -            Logger.backendLogger.errorAndCrash("No sync")
   57.17 +            Log.shared.errorAndCrash("No sync")
   57.18              handle(error: BackgroundError.GeneralError.illegalState(info: "No sync"))
   57.19              return
   57.20          }
   57.21 @@ -168,7 +168,7 @@
   57.22  class SyncMessagesSyncDelegate: DefaultImapSyncDelegate {
   57.23      override public func folderSyncCompleted(_ sync: ImapSync, notification: Notification?) {
   57.24          guard let _ = errorHandler else {
   57.25 -            Logger.backendLogger.errorAndCrash("We must have an errorHandler here")
   57.26 +            Log.shared.errorAndCrash("We must have an errorHandler here")
   57.27              return
   57.28          }
   57.29          (errorHandler as? SyncMessagesOperation)?.folderSyncCompleted(
   57.30 @@ -181,7 +181,7 @@
   57.31  
   57.32      override public  func folderOpenCompleted(_ sync: ImapSync, notification: Notification?) {
   57.33          guard let _ = errorHandler else {
   57.34 -            Logger.backendLogger.errorAndCrash("We must have an errorHandler here")
   57.35 +            Log.shared.errorAndCrash("We must have an errorHandler here")
   57.36              return
   57.37          }
   57.38          (errorHandler as? SyncMessagesOperation)?.folderOpenCompleted(
    58.1 --- a/MessageModel/MessageModel/NetworkService/Operations/UIDCopyOperation.swift	Fri May 03 12:19:46 2019 +0200
    58.2 +++ b/MessageModel/MessageModel/NetworkService/Operations/UIDCopyOperation.swift	Mon May 20 16:30:04 2019 +0200
    58.3 @@ -69,7 +69,7 @@
    58.4  
    58.5      override func folderOpenCompleted(_ sync: ImapSync, notification: Notification?) {
    58.6          guard let handler = errorHandler as? UIDCopyOperation else {
    58.7 -            Logger.backendLogger.errorAndCrash("No handler")
    58.8 +            Log.shared.errorAndCrash("No handler")
    58.9              return
   58.10          }
   58.11          handler.handleMessage()
   58.12 @@ -77,7 +77,7 @@
   58.13  
   58.14      override func messagesCopyCompleted(_ sync: ImapSync, notification: Notification?) {
   58.15          guard let handler = errorHandler as? UIDCopyOperation else {
   58.16 -            Logger.backendLogger.errorAndCrash("No handler")
   58.17 +            Log.shared.errorAndCrash("No handler")
   58.18              return
   58.19          }
   58.20          handler.markAsFinished()
   58.21 @@ -105,7 +105,7 @@
   58.22  
   58.23      private func handle(error: Error, on errorHandler: ImapSyncDelegateErrorHandlerProtocol?) {
   58.24          guard let handler = errorHandler as? UIDCopyOperation else {
   58.25 -            Logger.backendLogger.errorAndCrash("Wrong delegate called")
   58.26 +            Log.shared.errorAndCrash("Wrong delegate called")
   58.27              return
   58.28          }
   58.29          handler.addIMAPError(error)
    59.1 --- a/MessageModel/MessageModel/NetworkService/ReplicationService.swift	Fri May 03 12:19:46 2019 +0200
    59.2 +++ b/MessageModel/MessageModel/NetworkService/ReplicationService.swift	Mon May 20 16:30:04 2019 +0200
    59.3 @@ -155,7 +155,7 @@
    59.4      func networkServiceWorkerDidFinishLastSyncLoop(worker: NetworkServiceWorker) {
    59.5          GCD.onMain { [weak self] in
    59.6              guard let me = self else {
    59.7 -                Logger.frontendLogger.lostMySelf()
    59.8 +                Log.shared.lostMySelf()
    59.9                  return
   59.10              }
   59.11              me.delegate?.replicationServiceDidFinishLastSyncLoop(service: me)
   59.12 @@ -165,7 +165,7 @@
   59.13      func networkServiceWorkerDidCancel(worker: NetworkServiceWorker) {
   59.14          GCD.onMain { [weak self] in
   59.15              guard let me = self else {
   59.16 -                Logger.frontendLogger.lostMySelf()
   59.17 +                Log.shared.lostMySelf()
   59.18                  return
   59.19              }
   59.20              me.delegate?.replicationServiceDidCancel(service: me)
   59.21 @@ -175,7 +175,7 @@
   59.22      func networkServiceWorker(_ worker: NetworkServiceWorker, errorOccured error: Error) {
   59.23          GCD.onMain { [weak self] in
   59.24              guard let me = self else {
   59.25 -                Logger.frontendLogger.lostMySelf()
   59.26 +                Log.shared.lostMySelf()
   59.27                  return
   59.28              }
   59.29              me.serviceConfig.errorPropagator?.report(error: error)
    60.1 --- a/MessageModel/MessageModel/NetworkService/Service/SmtpService.swift	Fri May 03 12:19:46 2019 +0200
    60.2 +++ b/MessageModel/MessageModel/NetworkService/Service/SmtpService.swift	Mon May 20 16:30:04 2019 +0200
    60.3 @@ -205,7 +205,7 @@
    60.4                  group.enter()
    60.5                  token.performAction() { [weak self] error, freshToken in
    60.6                      if let err = error {
    60.7 -                        Logger.backendLogger.error(
    60.8 +                        Log.shared.error(
    60.9                              "%{public}@", err.localizedDescription)
   60.10                          if let theSelf = self {
   60.11                              theSelf.delegate?.authenticationFailed(theSelf, theNotification: nil)
   60.12 @@ -222,7 +222,7 @@
   60.13                                  group.leave()
   60.14                              }
   60.15                          } else {
   60.16 -                            Logger.backendLogger.lostMySelf()
   60.17 +                            Log.shared.lostMySelf()
   60.18                              group.leave()
   60.19  
   60.20                          }
   60.21 @@ -241,7 +241,7 @@
   60.22                  } else {
   60.23                      missingToken = "loginPassword"
   60.24                  }
   60.25 -                Logger.backendLogger.warn(
   60.26 +                Log.shared.warn(
   60.27                      "Don't have %{public}@ for %{public}@ (%{public}@)",
   60.28                      missingToken,
   60.29                      connectInfo.networkAddress,
    61.1 --- a/MessageModel/MessageModel/NetworkService/Service/VerificationByLogin/VerifiableAccountProtocol.swift	Fri May 03 12:19:46 2019 +0200
    61.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.3 @@ -1,99 +0,0 @@
    61.4 -//
    61.5 -//  VerifiableAccountProtocol.swift
    61.6 -//  MessageModel
    61.7 -//
    61.8 -//  Created by Dirk Zimmermann on 15.04.19.
    61.9 -//  Copyright © 2019 pEp Security S.A. All rights reserved.
   61.10 -//
   61.11 -
   61.12 -import Foundation
   61.13 -
   61.14 -import PantomimeFramework
   61.15 -
   61.16 -/// A type of known error that can be thrown by implementations.
   61.17 -/// - Note: There may be other types, i.e. from components below.
   61.18 -public enum VerifiableAccountError: Error {
   61.19 -    case invalidUserData
   61.20 -}
   61.21 -
   61.22 -/// The delegate used for the `VerifiableAccountProtocol`.
   61.23 -public protocol VerifiableAccountDelegate: class {
   61.24 -    /// Gets called once the verification has finished, successfully or not.
   61.25 -    /// The given `result` indicates success or failure.
   61.26 -    func didEndVerification(result: Result<Void, Error>)
   61.27 -}
   61.28 -
   61.29 -/// Objects that can verify accounts.
   61.30 -/// An account currently consist of user data (like login, password etc.)
   61.31 -/// and one IMAP and one SMTP server.
   61.32 -///
   61.33 -/// 1. Fill-in the data, like email address, server names etc.
   61.34 -/// 2. Set the delegate to a class under your control.
   61.35 -/// 3. Call `verify()`. This will throw if the given data is inconsistent.
   61.36 -/// 4. Your delegate will get called when the verification is finished, indicating
   61.37 -///    either success of failure.
   61.38 -/// 5. On success, call `save()` to persist this account.
   61.39 -///    `save()` will throw in any case `verify()` will throw (inconsistent data),
   61.40 -///    or when the verification was not successful.
   61.41 -public protocol VerifiableAccountProtocol {
   61.42 -    /// The email address of the account. Used for logging in to the servers.
   61.43 -    var address: String? { get set }
   61.44 -
   61.45 -    /// The actual name of the user, or nick name.
   61.46 -    /// Not to be confused with the login name.
   61.47 -    var userName: String? { get set }
   61.48 -
   61.49 -    /// An optional login name for the servers, if needed.
   61.50 -    /// Falls back to `address`.
   61.51 -    var loginName: String? { get set }
   61.52 -
   61.53 -    /// Currently, the only use case for this is `.saslXoauth2`.
   61.54 -    /// In all other cases, this should be nil.
   61.55 -    /// TODO: Indicate if this is valid for IMAP only, or both SMTP and IMAP.
   61.56 -    var authMethod: AuthMethod? { get set }
   61.57 -
   61.58 -    /// The password, if needed, to log in.
   61.59 -    /// Valid for both IMAP and SMTP servers.
   61.60 -    var password: String? { get set }
   61.61 -
   61.62 -    /// If the user chose OAuth2, this is the token. `password` then should be nil.
   61.63 -    /// If set, `authMethod` should be `.saslXoauth2`
   61.64 -    /// TODO: Indicate if this is valid for IMAP only, or both SMTP and IMAP.
   61.65 -    var accessToken: OAuth2AccessTokenProtocol? { get set }
   61.66 -
   61.67 -    /// The address of the IMAP server, like 'imap.example.com'.
   61.68 -    var serverIMAP: String? { get set }
   61.69 -
   61.70 -    /// The port the IMAP server listens on for new connections.
   61.71 -    var portIMAP: UInt16 { get set }
   61.72 -
   61.73 -    /// The transport to be used for IMAP, like TLS.
   61.74 -    var transportIMAP: ConnectionTransport { get set }
   61.75 -
   61.76 -    /// The address of the SMTP server, like 'smtp.example.com'.
   61.77 -    var serverSMTP: String? { get set }
   61.78 -
   61.79 -    /// The port the SMTP server listens on for new connections.
   61.80 -    var portSMTP: UInt16 { get set }
   61.81 -
   61.82 -    /// The transport to be used for SMTP, like TLS.
   61.83 -    var transportSMTP: ConnectionTransport { get set }
   61.84 -
   61.85 -    /// Indicates that the IMAP server is to be trusted.
   61.86 -    var trustedImapServer: Bool { get set }
   61.87 -
   61.88 -    /// The delegate to inform when the process has finished, either successfully or not.
   61.89 -    var verifiableAccountDelegate: VerifiableAccountDelegate? { get set }
   61.90 -
   61.91 -    /// Starts login attempts in the background to the indicated servers,
   61.92 -    /// informing the delegate (`verifiableAccountDelegate`) when finished.
   61.93 -    /// - Note: Throws for missing data.
   61.94 -    /// - Throws:
   61.95 -    func verify() throws
   61.96 -
   61.97 -    /// If the verification was successful, saves the account.
   61.98 -    /// - Note: Thows for missing data (i.e., all cases when `verify()` would throw),
   61.99 -    ///   and also if no successfull verification took place before.
  61.100 -    /// - Throws:
  61.101 -    func save() throws
  61.102 -}
    62.1 --- a/MessageModel/MessageModel/NetworkService/Util/Attachment+Extension.swift	Fri May 03 12:19:46 2019 +0200
    62.2 +++ b/MessageModel/MessageModel/NetworkService/Util/Attachment+Extension.swift	Mon May 20 16:30:04 2019 +0200
    62.3 @@ -13,7 +13,7 @@
    62.4       Can this attachment be shown in the app?
    62.5       */
    62.6      public func isViewable() -> Bool {  
    62.7 -        if data == nil || AttachmentFilter.unviewableMimeTypes.contains(mimeType.lowercased()) {
    62.8 +        if data == nil || MimeTypeUtils.unviewableMimeTypes.contains(mimeType.lowercased()) {
    62.9              return false
   62.10          }
   62.11          return true
    63.1 --- a/MessageModel/MessageModel/NetworkService/Util/CWIMAPMessage+pEp.swift	Fri May 03 12:19:46 2019 +0200
    63.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CWIMAPMessage+pEp.swift	Mon May 20 16:30:04 2019 +0200
    63.3 @@ -85,11 +85,11 @@
    63.4              // Create multipart mail
    63.5              let multiPart = CWMIMEMultipart()
    63.6              if isEncrypted {
    63.7 -                self.setContentType(Constants.contentTypeMultipartEncrypted)
    63.8 +                self.setContentType(ContentTypeUtils.ContentType.multipartEncrypted)
    63.9                  self.setContentTransferEncoding(PantomimeEncoding8bit)
   63.10 -                self.setParameter(Constants.protocolPGPEncrypted, forKey: "protocol")
   63.11 +                self.setParameter(ContentTypeUtils.ContentType.pgpEncrypted, forKey: "protocol")
   63.12              } else {
   63.13 -                self.setContentType(Constants.contentTypeMultipartRelated)
   63.14 +                self.setContentType(ContentTypeUtils.ContentType.multipartRelated)
   63.15                  self.setContentTransferEncoding(PantomimeEncoding8bit)
   63.16                  if let bodyPart = PEPUtil.bodyPart(pEpMessageDict: pEpMessageDict) {
   63.17                      multiPart.add(bodyPart)
    64.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdAccount+Extension.swift	Fri May 03 12:19:46 2019 +0200
    64.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdAccount+Extension.swift	Mon May 20 16:30:04 2019 +0200
    64.3 @@ -21,7 +21,7 @@
    64.4                  server.serverType == Server.ServerType.imap ||
    64.5                      server.serverType == Server.ServerType.smtp
    64.6                  else {
    64.7 -                    Logger.modelLogger.errorAndCrash("Unsupported server type")
    64.8 +                    Log.shared.errorAndCrash("Unsupported server type")
    64.9                      continue
   64.10              }
   64.11  
   64.12 @@ -43,15 +43,11 @@
   64.13          guard
   64.14              let emailProtocol = EmailProtocol(serverType: server.serverType)
   64.15              else {
   64.16 -                Logger.modelLogger.errorAndCrash("Missing emailProtocol")
   64.17 +                Log.shared.errorAndCrash("Missing emailProtocol")
   64.18                  return nil
   64.19          }
   64.20  
   64.21 -        let trusedServer =
   64.22 -            server.trusted ||
   64.23 -                NetworkServiceConfig.manuallyTrustedServerTagger.isManuallyTrustedServer(
   64.24 -                    address: identityOrCrash.addressOrCrash)
   64.25 -
   64.26 +        let trusedServer = server.automaticallyTrusted || server.manuallyTrusted
   64.27          return EmailConnectInfo(account: self,
   64.28                                  server: server,
   64.29                                  credentials: credentials,
    65.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdAccount+pEp.swift	Fri May 03 12:19:46 2019 +0200
    65.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdAccount+pEp.swift	Mon May 20 16:30:04 2019 +0200
    65.3 @@ -25,7 +25,7 @@
    65.4              return nil
    65.5          }
    65.6          if serversForType.count > 1 {
    65.7 -            Logger.backendLogger.errorAndCrash(
    65.8 +            Log.shared.errorAndCrash(
    65.9                  "No servers of type %d for IMAP account %{public}@",
   65.10                  type.rawValue, identity?.address ?? "nil")
   65.11          }
    66.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdFolder+Extension.swift	Fri May 03 12:19:46 2019 +0200
    66.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdFolder+Extension.swift	Mon May 20 16:30:04 2019 +0200
    66.3 @@ -11,8 +11,6 @@
    66.4  import pEpIOSToolbox
    66.5  
    66.6  public extension CdFolder {
    66.7 -    @nonobjc static let comp = "CdFolder"
    66.8 -
    66.9      /**
   66.10       If the folder has been deleted, undelete it.
   66.11       -Returns: True if the folder was actually flagged for deletion.
   66.12 @@ -48,7 +46,7 @@
   66.13                                        selectable: Bool = true,
   66.14                                        account: CdAccount) -> (CdFolder, Bool)? {
   66.15          guard let moc = account.managedObjectContext else {
   66.16 -            Logger.modelLogger.errorAndCrash("ManagedObject without context")
   66.17 +            Log.shared.errorAndCrash("ManagedObject without context")
   66.18              return nil
   66.19          }
   66.20          var result: (CdFolder, Bool)?
   66.21 @@ -163,7 +161,7 @@
   66.22      /// - Returns: guessed type
   66.23      static private func guessFolderType(for folder: CdFolder) -> FolderType? {
   66.24          guard let folderName = folder.name else {
   66.25 -            Logger.modelLogger.errorAndCrash("We need the name to guess the type")
   66.26 +            Log.shared.errorAndCrash("We need the name to guess the type")
   66.27              return nil
   66.28          }
   66.29          if folderName.uppercased() == ImapSync.defaultImapInboxName.uppercased() {
    67.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdFolder+IMAP.swift	Fri May 03 12:19:46 2019 +0200
    67.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdFolder+IMAP.swift	Mon May 20 16:30:04 2019 +0200
    67.3 @@ -48,7 +48,7 @@
    67.4          let pIsRemote = CdFolder.PredicateFactory.isSyncedWithServer()
    67.5          let p = NSCompoundPredicate(andPredicateWithSubpredicates: [pInAccount, pIsRemote])
    67.6          guard let cdFolders = CdFolder.all(predicate: p) as? [CdFolder] else {
    67.7 -            Logger.modelLogger.errorAndCrash("Error casting")
    67.8 +            Log.shared.errorAndCrash("Error casting")
    67.9              return result
   67.10          }
   67.11  
    68.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdIdentity+pEp.swift	Fri May 03 12:19:46 2019 +0200
    68.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdIdentity+pEp.swift	Mon May 20 16:30:04 2019 +0200
    68.3 @@ -37,7 +37,7 @@
    68.4          identity.save()
    68.5  
    68.6          guard let result = CdIdentity.search(address: pEpC.address) else {
    68.7 -            Logger.modelLogger.errorAndCrash(
    68.8 +            Log.shared.errorAndCrash(
    68.9                  "We have just saved this identity. It has to exist.")
   68.10              return CdIdentity.create()
   68.11          }
    69.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdMessage+Clone.swift	Fri May 03 12:19:46 2019 +0200
    69.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdMessage+Clone.swift	Mon May 20 16:30:04 2019 +0200
    69.3 @@ -18,7 +18,7 @@
    69.4       * imap (CdImapFields)
    69.5  
    69.6       */
    69.7 -    public func clone() -> CdMessage {
    69.8 +    public func cloneWithZeroUID() -> CdMessage {
    69.9          let m = CdMessage.create(context: managedObjectContext)
   69.10  
   69.11          m.comments = comments
   69.12 @@ -29,7 +29,7 @@
   69.13          m.received = received
   69.14          m.sent = sent
   69.15          m.shortMessage = shortMessage
   69.16 -        m.uid = uid
   69.17 +        m.uid = 0
   69.18          m.underAttack = underAttack
   69.19          m.uuid = uuid
   69.20  
    70.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdMessage+Extension.swift	Fri May 03 12:19:46 2019 +0200
    70.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdMessage+Extension.swift	Mon May 20 16:30:04 2019 +0200
    70.3 @@ -60,7 +60,7 @@
    70.4          guard
    70.5              let cdParentFolder = msg.parent.cdFolder(),
    70.6              let from = msg.from?.cdIdentity() else {
    70.7 -            Log.shared.errorAndCrash(component: #function, errorString: "No parent")
    70.8 +            Log.shared.errorAndCrash("No parent")
    70.9              return nil
   70.10          }
   70.11          let createe = CdMessage.create()
    71.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdMessage+Fake.swift	Fri May 03 12:19:46 2019 +0200
    71.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdMessage+Fake.swift	Mon May 20 16:30:04 2019 +0200
    71.3 @@ -19,7 +19,7 @@
    71.4       Clones this message and notifies the UI with it.
    71.5       */
    71.6      public func createFakeMessageAndNotify() {
    71.7 -        let fakeMsg = clone()
    71.8 +        let fakeMsg = cloneWithZeroUID()
    71.9          fakeMsg.uid = Int32(CdMessage.uidFakeResponsivenes)
   71.10          Record.saveAndWait()
   71.11          if let msg = MessageModelObjectUtils().getMessage(fromCdMessage:fakeMsg) {
    72.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdMessage+IMAP.swift	Fri May 03 12:19:46 2019 +0200
    72.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdMessage+IMAP.swift	Mon May 20 16:30:04 2019 +0200
    72.3 @@ -29,7 +29,7 @@
    72.4      /// The caller is responsible for saving.
    72.5      private func internalImapMarkDeleted() {
    72.6          guard self.parentOrCrash.folderType.isSyncedWithServer else {
    72.7 -            Logger.modelLogger.errorAndCrash(
    72.8 +            Log.shared.errorAndCrash(
    72.9                  "This method must not be called for messages in local folders.")
   72.10              return
   72.11          }
    73.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdMessage+Pantomime.swift	Fri May 03 12:19:46 2019 +0200
    73.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdMessage+Pantomime.swift	Mon May 20 16:30:04 2019 +0200
    73.3 @@ -24,7 +24,7 @@
    73.4          if let fl = PantomimeFlag(rawValue: UInt(flags)) {
    73.5              return CWFlags(flags: fl)
    73.6          }
    73.7 -        Logger.modelLogger.error("Could not convert %d to PantomimeFlag", flags)
    73.8 +        Log.shared.error("Could not convert %d to PantomimeFlag", flags)
    73.9          return CWFlags()
   73.10      }
   73.11  
   73.12 @@ -64,7 +64,7 @@
   73.13          if let fl = PantomimeFlag(rawValue: UInt(flagsInt16)) {
   73.14              return CWFlags(flags: fl)
   73.15          }
   73.16 -        Logger.modelLogger.error("Could not convert %d to PantomimeFlag", flagsInt16)
   73.17 +        Log.shared.error("Could not convert %d to PantomimeFlag", flagsInt16)
   73.18          return CWFlags()
   73.19      }
   73.20  
   73.21 @@ -82,7 +82,7 @@
   73.22          var dict: [AnyHashable: Any] = [PantomimeMessagesKey: NSArray.init(object: pantomimeMail)]
   73.23  
   73.24          guard let imap = imap else {
   73.25 -            Logger.modelLogger.errorAndCrash("imap == nil")
   73.26 +            Log.shared.errorAndCrash("imap == nil")
   73.27              return [AnyHashable: Any]()
   73.28          }
   73.29  
   73.30 @@ -416,7 +416,7 @@
   73.31          // Bail out quickly if there is only a flag change needed
   73.32          if messageUpdate.isFlagsOnly() {
   73.33              guard isUpdate else {
   73.34 -                Logger.modelLogger.errorAndCrash(
   73.35 +                Log.shared.errorAndCrash(
   73.36                      "If only flags did change, the message must have existed before. Thus it must be an update.")
   73.37                  return nil
   73.38              }
   73.39 @@ -495,7 +495,7 @@
   73.40              // This is a contradiction in itself, a new message that already existed.
   73.41              // Can happen with yahoo IMAP servers when they send more messages in
   73.42              // FETCH responses than requested.
   73.43 -            Logger.modelLogger.warn(
   73.44 +            Log.shared.warn(
   73.45                  "ignoring rfc2822 update for already decrypted message")
   73.46              return mail
   73.47          }
   73.48 @@ -517,7 +517,7 @@
   73.49                  case .bccRecipient:
   73.50                      bccs.add(cdIdentity(pantomimeAddress: addr))
   73.51                  default:
   73.52 -                    Logger.modelLogger.warn(
   73.53 +                    Log.shared.warn(
   73.54                          "Unsupported recipient type %d for %{public}@",
   73.55                          addr.type().rawValue,
   73.56                          addr.address())
   73.57 @@ -617,7 +617,7 @@
   73.58      static func search(message: CWIMAPMessage, inAccount account: CdAccount) -> CdMessage? {
   73.59          let uid = Int32(message.uid())
   73.60          guard let uuid = message.messageID() else {
   73.61 -            Log.shared.errorAndCrash(component: #function, errorString: "No UUID")
   73.62 +            Log.shared.errorAndCrash("No UUID")
   73.63              return nil
   73.64          }
   73.65          return search(uid: uid,
   73.66 @@ -643,7 +643,7 @@
   73.67          identity.save()
   73.68  
   73.69          guard let result = CdIdentity.search(address: theEmail) else {
   73.70 -            Logger.modelLogger.errorAndCrash(
   73.71 +            Log.shared.errorAndCrash(
   73.72                  "We have just saved this identity. It has to exist.")
   73.73              return CdIdentity.create()
   73.74          }
   73.75 @@ -660,8 +660,8 @@
   73.76              return
   73.77          }
   73.78  
   73.79 -        let isText = part.contentType()?.lowercased() == Constants.contentTypeText
   73.80 -        let isHtml = part.contentType()?.lowercased() == Constants.contentTypeHtml
   73.81 +        let isText = part.contentType()?.lowercased() == ContentTypeUtils.ContentType.plainText
   73.82 +        let isHtml = part.contentType()?.lowercased() == ContentTypeUtils.ContentType.html
   73.83          var contentData: Data?
   73.84          if let message = content as? CWMessage {
   73.85              contentData = message.dataValue()
    74.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdMessage+pEp.swift	Fri May 03 12:19:46 2019 +0200
    74.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdMessage+pEp.swift	Mon May 20 16:30:04 2019 +0200
    74.3 @@ -135,7 +135,7 @@
    74.4  
    74.5      func outgoingMessageRating() -> PEPRating {
    74.6          guard let sender = from else {
    74.7 -            Logger.modelLogger.errorAndCrash(
    74.8 +            Log.shared.errorAndCrash(
    74.9                  "No sender for outgoing message?")
   74.10              return .undefined
   74.11          }
   74.12 @@ -162,10 +162,8 @@
   74.13              // Some tests seem to think that this is a valid case. Don't crash.
   74.14              return false
   74.15          }
   74.16 -        let accountHasBeenCreatedInLocalNetwork = imapServer.trusted
   74.17 -        let userDecidedToTrustServer =
   74.18 -            NetworkServiceConfig.manuallyTrustedServerTagger.isManuallyTrustedServer(
   74.19 -                address: parentOrCrash.accountOrCrash.identityOrCrash.addressOrCrash)
   74.20 +        let accountHasBeenCreatedInLocalNetwork = imapServer.automaticallyTrusted
   74.21 +        let userDecidedToTrustServer = imapServer.manuallyTrusted
   74.22          return accountHasBeenCreatedInLocalNetwork || userDecidedToTrustServer
   74.23      }
   74.24  
    75.1 --- a/MessageModel/MessageModel/NetworkService/Util/CdMessagePredicateFactory+Extension.swift	Fri May 03 12:19:46 2019 +0200
    75.2 +++ b/MessageModel/MessageModel/NetworkService/Util/CdMessagePredicateFactory+Extension.swift	Mon May 20 16:30:04 2019 +0200
    75.3 @@ -34,7 +34,7 @@
    75.4              format: "(SUBQUERY(%K, $a, (not ($a.%K in %@)))).@count > 0",
    75.5              CdMessage.RelationshipName.attachments,
    75.6              CdAttachment.AttributeName.mimeType,
    75.7 -            AttachmentFilter.unviewableMimeTypes)
    75.8 +            MimeTypeUtils.unviewableMimeTypes)
    75.9          return NSCompoundPredicate(andPredicateWithSubpredicates: [notUnencryptable, viewableOnly])
   75.10      }
   75.11  
    76.1 --- a/MessageModel/MessageModel/NetworkService/Util/ContentDispositionType+Conversion.swift	Fri May 03 12:19:46 2019 +0200
    76.2 +++ b/MessageModel/MessageModel/NetworkService/Util/ContentDispositionType+Conversion.swift	Mon May 20 16:30:04 2019 +0200
    76.3 @@ -24,7 +24,7 @@
    76.4          case .other:
    76.5              return PantomimeAttachmentDisposition
    76.6          default:
    76.7 -            Logger.modelLogger.errorAndCrash("Unknown case")
    76.8 +            Log.shared.errorAndCrash("Unknown case")
    76.9              return PantomimeAttachmentDisposition
   76.10          }
   76.11      }
   76.12 @@ -49,7 +49,7 @@
   76.13          case .inline:
   76.14              return PantomimeInlineDisposition
   76.15          case .other:
   76.16 -            Logger.modelLogger.errorAndCrash("Attachment disposition: other")
   76.17 +            Log.shared.errorAndCrash("Attachment disposition: other")
   76.18              return PantomimeAttachmentDisposition
   76.19          }
   76.20      }
   76.21 @@ -61,7 +61,7 @@
   76.22          case .inline:
   76.23              return PEPContentDisposition.inline
   76.24          case .other:
   76.25 -            Logger.modelLogger.errorAndCrash("Attachment disposition: other")
   76.26 +            Log.shared.errorAndCrash("Attachment disposition: other")
   76.27              return PEPContentDisposition.attachment
   76.28          }
   76.29      }
   76.30 @@ -75,7 +75,7 @@
   76.31          case .other:
   76.32              self = .attachment // This is probably wrong. Semantic of other not clear
   76.33          default:
   76.34 -            Logger.modelLogger.errorAndCrash("Unknown case")
   76.35 +            Log.shared.errorAndCrash("Unknown case")
   76.36              self = .attachment
   76.37          }
   76.38      }
   76.39 @@ -87,7 +87,7 @@
   76.40          case PantomimeInlineDisposition:
   76.41              self = .inline
   76.42          default:
   76.43 -            Logger.modelLogger.errorAndCrash("Unknown case")
   76.44 +            Log.shared.errorAndCrash("Unknown case")
   76.45              self = .attachment
   76.46          }
   76.47      }
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/MessageModel/MessageModel/NetworkService/Util/ContentTypeUtils.swift	Mon May 20 16:30:04 2019 +0200
    77.3 @@ -0,0 +1,27 @@
    77.4 +//
    77.5 +//  ContentTypeUtils.swift
    77.6 +//  MessageModel
    77.7 +//
    77.8 +//  Created by Alejandro Gelos on 07/05/2019.
    77.9 +//  Copyright © 2019 pEp Security S.A. All rights reserved.
   77.10 +//
   77.11 +
   77.12 +import Foundation
   77.13 +
   77.14 +public struct ContentTypeUtils {
   77.15 +    public struct ContentType {
   77.16 +        public static let pgpKeys = "application/pgp-keys"
   77.17 +        public static let pgpEncrypted = "application/pgp-encrypted"
   77.18 +        public static let html = "text/html"
   77.19 +        public static let plainText = "text/plain"
   77.20 +        public static let multipartMixed = "multipart/mixed"
   77.21 +        public static let multipartEncrypted = "multipart/encrypted"
   77.22 +        public static let multipartRelated = "multipart/related"
   77.23 +        public static let multipartAlternative = "multipart/alternative"
   77.24 +
   77.25 +        public struct Parameter {
   77.26 +            public static let pgpEncrypted = "application/pgp-encrypted"
   77.27 +        }
   77.28 +    }
   77.29 +}
   77.30 +
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/MessageModel/MessageModel/NetworkService/Util/EmailConnectInfo.swift	Mon May 20 16:30:04 2019 +0200
    78.3 @@ -0,0 +1,147 @@
    78.4 +//
    78.5 +//  EmailConnectInfo.swift
    78.6 +//  pEp
    78.7 +//
    78.8 +//  Created by Andreas Buff on 23.07.18.
    78.9 +//  Copyright © 2018 p≡p Security S.A. All rights reserved.
   78.10 +//
   78.11 +
   78.12 +import PantomimeFramework
   78.13 +import CoreData
   78.14 +
   78.15 +extension ConnectionTransport {
   78.16 +    public init?(fromInt: Int?) {
   78.17 +        guard let i = fromInt else {
   78.18 +            return nil
   78.19 +        }
   78.20 +        switch i {
   78.21 +        case ConnectionTransport.plain.rawValue:
   78.22 +            self = ConnectionTransport.plain
   78.23 +        case ConnectionTransport.startTLS.rawValue:
   78.24 +            self = ConnectionTransport.startTLS
   78.25 +        case ConnectionTransport.TLS.rawValue:
   78.26 +            self = ConnectionTransport.TLS
   78.27 +        default:
   78.28 +            return nil
   78.29 +        }
   78.30 +    }
   78.31 +
   78.32 +    public static func fromInteger(_ i: Int) -> ConnectionTransport {
   78.33 +        switch i {
   78.34 +        case ConnectionTransport.plain.rawValue:
   78.35 +            return ConnectionTransport.plain
   78.36 +        case ConnectionTransport.startTLS.rawValue:
   78.37 +            return ConnectionTransport.startTLS
   78.38 +        case ConnectionTransport.TLS.rawValue:
   78.39 +            return ConnectionTransport.TLS
   78.40 +        default:
   78.41 +            abort()
   78.42 +        }
   78.43 +    }
   78.44 +
   78.45 +    public func localizedString() -> String {
   78.46 +        let transport_security_text = "Transport security (ConnectionTransport)"
   78.47 +        switch self {
   78.48 +        case .plain:
   78.49 +            return NSLocalizedString("None", comment: transport_security_text)
   78.50 +        case .TLS:
   78.51 +            return NSLocalizedString("TLS", comment: transport_security_text)
   78.52 +        case .startTLS:
   78.53 +            return NSLocalizedString("StartTLS", comment: transport_security_text)
   78.54 +        }
   78.55 +    }
   78.56 +
   78.57 +    // XXX: Here material from the Model area is used: to be avoided or code-shared.
   78.58 +    public func toServerTransport() -> Server.Transport {
   78.59 +        switch self {
   78.60 +        case .plain: return Server.Transport.plain
   78.61 +        case .TLS: return Server.Transport.tls
   78.62 +        case .startTLS: return Server.Transport.startTls
   78.63 +        }
   78.64 +    }
   78.65 +}
   78.66 +
   78.67 +public enum EmailProtocol: String {
   78.68 +    case smtp = "SMTP"
   78.69 +    case imap = "IMAP"
   78.70 +
   78.71 +    public init?(emailProtocol: String) {
   78.72 +        if emailProtocol.isEqual(EmailProtocol.smtp.rawValue) {
   78.73 +            self = .smtp
   78.74 +        } else if emailProtocol.isEqual(EmailProtocol.imap.rawValue) {
   78.75 +            self = .imap
   78.76 +        } else {
   78.77 +            return nil
   78.78 +        }
   78.79 +    }
   78.80 +
   78.81 +    public init?(serverType: Server.ServerType?) {
   78.82 +        guard let st = serverType else {
   78.83 +            return nil
   78.84 +        }
   78.85 +        switch st {
   78.86 +        case .imap:
   78.87 +            self = .imap
   78.88 +        case .smtp:
   78.89 +            self = .smtp
   78.90 +        }
   78.91 +    }
   78.92 +}
   78.93 +
   78.94 +public class EmailConnectInfo: ConnectInfo {
   78.95 +    enum EmailConnectInfoError: Error {
   78.96 +        case cannotFindServerCredentials
   78.97 +    }
   78.98 +
   78.99 +    let emailProtocol: EmailProtocol?
  78.100 +    let connectionTransport: ConnectionTransport?
  78.101 +    let authMethod: AuthMethod?
  78.102 +
  78.103 +    /// There is either the `loginPassword`, or this, but there should never exist both.
  78.104 +    /// If non-nil, the `authMethod` is expected to be `AuthMethod.saslXoauth2`.
  78.105 +    var accessToken: OAuth2AccessTokenProtocol? {
  78.106 +        guard authMethod == .saslXoauth2,
  78.107 +            let key = loginPasswordKeyChainKey,
  78.108 +            let token = KeyChain.serverPassword(forKey: key) else {
  78.109 +                return nil
  78.110 +        }
  78.111 +        return OAuth2AccessToken.from(base64Encoded: token) as? OAuth2AccessTokenProtocol
  78.112 +    }
  78.113 +
  78.114 +    func isTrusted(context: NSManagedObjectContext) -> Bool {
  78.115 +        var isTrusted = false
  78.116 +        context.performAndWait {
  78.117 +            let cdAccount = context.object(with: account.objectID) as! CdAccount
  78.118 +            isTrusted = cdAccount.isTrusted
  78.119 +        }
  78.120 +        return isTrusted
  78.121 +    }
  78.122 +
  78.123 +    init(account: CdAccount,
  78.124 +         server: CdServer,
  78.125 +         credentials: CdServerCredentials,
  78.126 +         loginName: String? = nil,
  78.127 +         loginPasswordKeyChainKey: String? = nil,
  78.128 +         networkAddress: String,
  78.129 +         networkPort: UInt16,
  78.130 +         networkAddressType: NetworkAddressType? = nil,
  78.131 +         networkTransportType: NetworkTransportType? = nil,
  78.132 +         emailProtocol: EmailProtocol? = nil,
  78.133 +         connectionTransport: ConnectionTransport? = nil,
  78.134 +         authMethod: AuthMethod? = nil,
  78.135 +         trusted: Bool = false) {
  78.136 +        self.emailProtocol = emailProtocol
  78.137 +        self.connectionTransport = connectionTransport
  78.138 +        self.authMethod = authMethod
  78.139 +
  78.140 +        super.init(account: account,
  78.141 +                   server: server,
  78.142 +                   credentials: credentials,
  78.143 +                   loginName: loginName,
  78.144 +                   loginPasswordKeyChainKey: loginPasswordKeyChainKey,
  78.145 +                   networkAddress: networkAddress,
  78.146 +                   networkPort: networkPort,
  78.147 +                   networkAddressType: networkAddressType,
  78.148 +                   networkTransportType: networkTransportType)
  78.149 +    }
  78.150 +}
    79.1 --- a/MessageModel/MessageModel/NetworkService/Util/Folder+Imap.swift	Fri May 03 12:19:46 2019 +0200
    79.2 +++ b/MessageModel/MessageModel/NetworkService/Util/Folder+Imap.swift	Mon May 20 16:30:04 2019 +0200
    79.3 @@ -31,7 +31,7 @@
    79.4          let pIsRemote = CdFolder.PredicateFactory.isSyncedWithServer()
    79.5          let p = NSCompoundPredicate(andPredicateWithSubpredicates: [pInAccount, pIsRemote])
    79.6          guard let cdFolders = CdFolder.all(predicate: p) as? [CdFolder] else {
    79.7 -            Logger.modelLogger.errorAndCrash("Error casting")
    79.8 +            Log.shared.errorAndCrash("Error casting")
    79.9              return result
   79.10          }
   79.11          result =
    80.1 --- a/MessageModel/MessageModel/NetworkService/Util/Message+IMAP.swift	Fri May 03 12:19:46 2019 +0200
    80.2 +++ b/MessageModel/MessageModel/NetworkService/Util/Message+IMAP.swift	Mon May 20 16:30:04 2019 +0200
    80.3 @@ -42,7 +42,7 @@
    80.4      /// TODO: This is mirrored in CdMessage. Reuse?
    80.5      private func internalImapMarkDeleted() {
    80.6          guard self.parent.folderType.isSyncedWithServer else {
    80.7 -            Logger.modelLogger.errorAndCrash(
    80.8 +            Log.shared.errorAndCrash(
    80.9                  "This method must not be called for messages in local folders.")
   80.10              return
   80.11          }
   80.12 @@ -57,12 +57,12 @@
   80.13      /// Note: Use only for messages synced with an IMAP server.
   80.14      private func internalImapDelete() {
   80.15          guard self.parent.folderType.isSyncedWithServer else {
   80.16 -            Logger.modelLogger.errorAndCrash(
   80.17 +            Log.shared.errorAndCrash(
   80.18                  "This method must not be called for messages in local folders.")
   80.19              return
   80.20          }
   80.21          guard let trashFolder = parent.account.folder(ofType: .trash) else {
   80.22 -            Logger.modelLogger.errorAndCrash(
   80.23 +            Log.shared.errorAndCrash(
   80.24                  "We should have a trash folder at this point")
   80.25              return
   80.26          }
    81.1 --- a/MessageModel/MessageModel/NetworkService/Util/Message+pEp.swift	Fri May 03 12:19:46 2019 +0200
    81.2 +++ b/MessageModel/MessageModel/NetworkService/Util/Message+pEp.swift	Mon May 20 16:30:04 2019 +0200
    81.3 @@ -25,10 +25,8 @@
    81.4              // Some tests seem to think that this is a valid case. Don't crash.
    81.5              return false
    81.6          }
    81.7 -        let accountHasBeenCreatedInLocalNetwork = imapServer.trusted
    81.8 -        let userDecidedToTrustServer =
    81.9 -            NetworkServiceConfig.manuallyTrustedServerTagger.isManuallyTrustedServer(
   81.10 -                address: parent.account.user.address)
   81.11 +        let accountHasBeenCreatedInLocalNetwork = imapServer.automaticallyTrusted
   81.12 +        let userDecidedToTrustServer = imapServer.manuallyTrusted
   81.13          return accountHasBeenCreatedInLocalNetwork || userDecidedToTrustServer
   81.14      }
   81.15  
   81.16 @@ -38,7 +36,7 @@
   81.17          }
   81.18  
   81.19          guard let sender = from else {
   81.20 -            Logger.modelLogger.errorAndCrash(
   81.21 +            Log.shared.errorAndCrash(
   81.22                  "No sender for outgoing message?")
   81.23              return .undefined
   81.24          }
    82.1 --- a/MessageModel/MessageModel/NetworkService/Util/MimeTypeUtil.swift	Fri May 03 12:19:46 2019 +0200
    82.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.3 @@ -1,71 +0,0 @@
    82.4 -//
    82.5 -//  MimeTypeUtil.swift
    82.6 -//  pEpForiOS
    82.7 -//
    82.8 -//  Created by Xavier Algarra on 08/02/17.
    82.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   82.10 -//
   82.11 -
   82.12 -import Foundation
   82.13 -
   82.14 -import pEpIOSToolbox
   82.15 -
   82.16 -open class MimeTypeUtil {
   82.17 -    public static let defaultMimeType = "application/octet-stream"
   82.18 -    public static let jpegMimeType = "image/jpeg"
   82.19 -
   82.20 -    /**
   82.21 -     Content type/mime type for attached keys.
   82.22 -     */
   82.23 -    public static let contentTypeApplicationPGPKeys = "application/pgp-keys"
   82.24 -
   82.25 -    private let comp = "MimeTypeUtil"
   82.26 -    private var mimeTypeToExtension = [String: String]()
   82.27 -    private var extensionToMimeType = [String: String]()
   82.28 -
   82.29 -    public init?() {
   82.30 -        let resource = "jsonMimeType"
   82.31 -        let type = "txt"
   82.32 -        do {
   82.33 -            if let file = Bundle.main.path(forResource: resource, ofType: type) {
   82.34 -                let data = try Data(contentsOf: URL(fileURLWithPath: file))
   82.35 -                guard let json = try JSONSerialization.jsonObject(with: data, options: [])
   82.36 -                    as? [String:Any] else {
   82.37 -                        return nil
   82.38 -                }
   82.39 -                guard let theData = json["mimeType"] as? [String: String] else {
   82.40 -                    return nil
   82.41 -                }
   82.42 -                for (theExtension, mimeType) in theData {
   82.43 -                    mimeTypeToExtension[mimeType.lowercased()] = theExtension
   82.44 -                    extensionToMimeType[theExtension.lowercased()] = mimeType
   82.45 -                }
   82.46 -                // "image/jpeg" is missing in ourt data. Fix it.
   82.47 -                mimeTypeToExtension[MimeTypeUtil.jpegMimeType] = "jpg"
   82.48 -            }
   82.49 -        } catch {
   82.50 -            Logger.utilLogger.log(error: error)
   82.51 -            return nil
   82.52 -        }
   82.53 -    }
   82.54 -
   82.55 -    open func fileExtension(mimeType: String) -> String? {
   82.56 -        return mimeTypeToExtension[mimeType.lowercased()]
   82.57 -    }
   82.58 -
   82.59 -    open func mimeType(fileExtension: String) -> String {
   82.60 -        return extensionToMimeType[fileExtension.lowercased()] ?? MimeTypeUtil.defaultMimeType
   82.61 -    }
   82.62 -
   82.63 -    /**
   82.64 -     Is the given mimetype suitable for creating an `UIImage`?
   82.65 -     */
   82.66 -    open func isImage(mimeType theMimeType: String) -> Bool {
   82.67 -        let lcMT = theMimeType.lowercased()
   82.68 -        if lcMT == mimeType(fileExtension: "png") || lcMT == mimeType(fileExtension: "jpg") ||
   82.69 -            lcMT == mimeType(fileExtension: "gif") {
   82.70 -            return true
   82.71 -        }
   82.72 -        return false
   82.73 -    }
   82.74 -}
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/MessageModel/MessageModel/NetworkService/Util/MimeTypeUtils.swift	Mon May 20 16:30:04 2019 +0200
    83.3 @@ -0,0 +1,82 @@
    83.4 +//
    83.5 +//  MimeTypeUtils.swift
    83.6 +//  pEpForiOS
    83.7 +//
    83.8 +//  Created by Xavier Algarra on 08/02/17.
    83.9 +//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   83.10 +//
   83.11 +
   83.12 +import Foundation
   83.13 +
   83.14 +public class MimeTypeUtils {
   83.15 +    public struct MimesType {
   83.16 +        public static let defaultMimeType = "application/octet-stream"
   83.17 +        public static let jpeg = "image/jpeg"
   83.18 +        public static let pgp =  "application/pgp-signature"
   83.19 +        public static let pdf  = "application/pdf"
   83.20 +        public static let pgpEncrypted = "application/pgp-encrypted"
   83.21 +        public static let attachedEmail = "message/rfc822"
   83.22 +    }
   83.23 +
   83.24 +    private var mimeTypeToExtension = [String: String]()
   83.25 +    private var extensionToMimeType = [String: String]()
   83.26 +
   83.27 +    public init?() {
   83.28 +        let resource = "jsonMimeType"
   83.29 +        let type = "txt"
   83.30 +        do {
   83.31 +            guard let bundle = Bundle(identifier: "net.pep-security.apps.MessageModel"),
   83.32 +                  let file = bundle.path(forResource: resource, ofType: type) else {
   83.33 +                    return
   83.34 +            }
   83.35 +            let data = try Data(contentsOf: URL(fileURLWithPath: file))
   83.36 +            guard let json = try JSONSerialization.jsonObject(with: data, options: [])
   83.37 +                as? [String: Any] else {
   83.38 +                    return nil
   83.39 +            }
   83.40 +            guard let theData = json["mimeType"] as? [String: String] else {
   83.41 +                return nil
   83.42 +            }
   83.43 +            for (theExtension, mimeType) in theData {
   83.44 +                mimeTypeToExtension[mimeType.lowercased()] = theExtension
   83.45 +                extensionToMimeType[theExtension.lowercased()] = mimeType
   83.46 +            }
   83.47 +            // "image/jpeg" is missing in ourt data. Fix it.
   83.48 +            mimeTypeToExtension[MimeTypeUtils.MimesType.jpeg] = "jpg"
   83.49 +        } catch {
   83.50 +            Log.shared.log(error: error)
   83.51 +            return nil
   83.52 +        }
   83.53 +    }
   83.54 +
   83.55 +    public func fileExtension(fromMimeType mimeType: String) -> String? {
   83.56 +        return mimeTypeToExtension[mimeType.lowercased()]
   83.57 +    }
   83.58 +
   83.59 +    public func mimeType(fromURL url: URL) -> String {
   83.60 +        return mimeType(fromFileExtension: url.pathExtension)
   83.61 +    }
   83.62 +
   83.63 +    public func mimeType(fromFileExtension fileExtension: String) -> String {
   83.64 +        return extensionToMimeType[fileExtension.lowercased()] ?? MimeTypeUtils.MimesType.defaultMimeType
   83.65 +    }
   83.66 +
   83.67 +    public static var unviewableMimeTypes: Set<String> {
   83.68 +        get {
   83.69 +            return Set([ContentTypeUtils.ContentType.pgpKeys, MimesType.pgp])
   83.70 +        }
   83.71 +    }
   83.72 +
   83.73 +    /**
   83.74 +     Is the given mimetype suitable for creating an `UIImage`?
   83.75 +     */
   83.76 +    public func isImage(mimeType theMimeType: String) -> Bool {
   83.77 +        let lcMT = theMimeType.lowercased()
   83.78 +        if lcMT == mimeType(fromFileExtension: "png") ||
   83.79 +           lcMT == mimeType(fromFileExtension: "jpg") ||
   83.80 +           lcMT == mimeType(fromFileExtension: "gif") {
   83.81 +            return true
   83.82 +        }
   83.83 +        return false
   83.84 +    }
   83.85 +}
    84.1 --- a/MessageModel/MessageModel/NetworkService/Util/NSSecureCoding+Extension.swift	Fri May 03 12:19:46 2019 +0200
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,30 +0,0 @@
    84.4 -//
    84.5 -//  NSSecureCoding+Extension.swift
    84.6 -//  pEp
    84.7 -//
    84.8 -//  Created by Dirk Zimmermann on 19.01.18.
    84.9 -//  Copyright © 2018 p≡p Security S.A. All rights reserved.
   84.10 -//
   84.11 -
   84.12 -import Foundation
   84.13 -
   84.14 -extension NSSecureCoding {
   84.15 -    /**
   84.16 -     Reconstructs an object from a string, that was created using `persistBase64Encoded()`.
   84.17 -     */
   84.18 -    static func from(base64Encoded: String) -> Any? {
   84.19 -        guard let data = Data(base64Encoded: base64Encoded) else {
   84.20 -            return nil
   84.21 -        }
   84.22 -        return NSKeyedUnarchiver.unarchiveObject(with: data)
   84.23 -    }
   84.24 -
   84.25 -    /**
   84.26 -     Persists itself into a string, using Base64 as the encoding.
   84.27 -     Works in tandem with `from(base64Encoded:)`.
   84.28 -     */
   84.29 -    public func persistBase64Encoded() -> String {
   84.30 -        let data = NSKeyedArchiver.archivedData(withRootObject: self)
   84.31 -        return data.base64EncodedString()
   84.32 -    }
   84.33 -}
    85.1 --- a/MessageModel/MessageModel/NetworkService/Util/PEPRating+Extension.swift	Fri May 03 12:19:46 2019 +0200
    85.2 +++ b/MessageModel/MessageModel/NetworkService/Util/PEPRating+Extension.swift	Mon May 20 16:30:04 2019 +0200
    85.3 @@ -74,7 +74,7 @@
    85.4               .underAttack:
    85.5              return true
    85.6          default:
    85.7 -            Logger.utilLogger.errorAndCrash(
    85.8 +            Log.shared.errorAndCrash(
    85.9                  "cannot decide isUnderAttack() for %{public}@", self.rawValue)
   85.10              return false
   85.11          }
   85.12 @@ -101,7 +101,7 @@
   85.13          case .underAttack:
   85.14              return true
   85.15          default:
   85.16 -            Logger.utilLogger.errorAndCrash(
   85.17 +            Log.shared.errorAndCrash(
   85.18                  "cannot decide isUnderAttack() for %{public}@", self.rawValue)
   85.19              return false
   85.20          }
    86.1 --- a/MessageModel/MessageModel/NetworkService/Util/PEPUtil.swift	Fri May 03 12:19:46 2019 +0200
    86.2 +++ b/MessageModel/MessageModel/NetworkService/Util/PEPUtil.swift	Mon May 20 16:30:04 2019 +0200
    86.3 @@ -20,8 +20,6 @@
    86.4  }
    86.5  
    86.6  public class PEPUtil {
    86.7 -    static let comp = "PEPUtil"
    86.8 -
    86.9      /**
   86.10       Default pEpRating value when there's none, i.e. the message has never been decrypted.
   86.11       */
   86.12 @@ -65,7 +63,7 @@
   86.13          if let id = account.identity {
   86.14              return pEpDict(cdIdentity: id)
   86.15          } else {
   86.16 -            Logger.utilLogger.errorAndCrash(
   86.17 +            Log.shared.errorAndCrash(
   86.18                  "account without identity: %{public}@", account)
   86.19              return PEPIdentity(address: "none")
   86.20          }
   86.21 @@ -99,7 +97,7 @@
   86.22                                 userName: cdIdentity.userName, isOwn: cdIdentity.isMySelf,
   86.23                                 fingerPrint: nil, commType: PEPCommType.unknown, language: nil)
   86.24          } else {
   86.25 -            Logger.utilLogger.errorAndCrash(
   86.26 +            Log.shared.errorAndCrash(
   86.27                  "missing address: %{public}@", cdIdentity)
   86.28              return PEPIdentity(address: "none")
   86.29          }
   86.30 @@ -139,7 +137,7 @@
   86.31          let contentDispoType = PEPContentDisposition(rawValue:
   86.32              Int(cdAttachment.contentDispositionTypeRawValue))
   86.33          if contentDispoType == nil {
   86.34 -            Logger.backendLogger.errorAndCrash(
   86.35 +            Log.shared.errorAndCrash(
   86.36                  "Unsupported PEPContentDisposition %d",
   86.37                  cdAttachment.contentDispositionTypeRawValue)
   86.38          }
   86.39 @@ -156,7 +154,7 @@
   86.40          let contentDispoType = PEPContentDisposition(rawValue:
   86.41              Int(attachment.contentDisposition.rawValue))
   86.42          if contentDispoType == nil {
   86.43 -            Logger.backendLogger.errorAndCrash(
   86.44 +            Log.shared.errorAndCrash(
   86.45                  "Unsupported PEPContentDisposition %d",
   86.46                  attachment.contentDisposition.rawValue)
   86.47          }
   86.48 @@ -336,7 +334,7 @@
   86.49              guard let filename = at.mimeType else {
   86.50                  continue
   86.51              }
   86.52 -            if filename.lowercased() == Constants.contentTypePGPEncrypted {
   86.53 +            if filename.lowercased() == ContentTypeUtils.ContentType.pgpEncrypted {
   86.54                  foundAttachmentPGPEncrypted = true
   86.55                  break
   86.56              }
   86.57 @@ -404,7 +402,7 @@
   86.58              return theBodyParts[0]
   86.59          } else if theBodyParts.count > 1 {
   86.60              let partAlt = CWPart()
   86.61 -            partAlt.setContentType(Constants.contentTypeMultipartAlternative)
   86.62 +            partAlt.setContentType(ContentTypeUtils.ContentType.multipartAlternative)
   86.63              let partMulti = CWMIMEMultipart()
   86.64              for part in theBodyParts {
   86.65                  partMulti.add(part)
   86.66 @@ -440,11 +438,11 @@
   86.67          var parts: [CWPart] = []
   86.68  
   86.69          if let part = makePart(text: pEpMessageDict[kPepLongMessage] as? String,
   86.70 -                               contentType: Constants.contentTypeText) {
   86.71 +                               contentType: ContentTypeUtils.ContentType.plainText) {
   86.72              parts.append(part)
   86.73          }
   86.74          if let part = makePart(text: pEpMessageDict[kPepLongMessageFormatted] as? String,
   86.75 -                               contentType: Constants.contentTypeHtml) {
   86.76 +                               contentType: ContentTypeUtils.ContentType.html) {
   86.77              parts.append(part)
   86.78          }
   86.79  
   86.80 @@ -473,7 +471,7 @@
   86.81          do {
   86.82              return try session.rating(for: pepC).pEpRating
   86.83          } catch {
   86.84 -            Logger.utilLogger.errorAndCrash(
   86.85 +            Log.shared.errorAndCrash(
   86.86                  "Identity: %{public}@ caused error: %{public}@",
   86.87                  identity.description, error.localizedDescription)
   86.88              return .undefined
    87.1 --- a/MessageModel/MessageModel/NetworkService/Util/String+Attachment.swift	Fri May 03 12:19:46 2019 +0200
    87.2 +++ b/MessageModel/MessageModel/NetworkService/Util/String+Attachment.swift	Mon May 20 16:30:04 2019 +0200
    87.3 @@ -22,7 +22,7 @@
    87.4              }
    87.5              return nil
    87.6          } catch {
    87.7 -            Logger.utilLogger.errorAndCrash("%{public}@", error.localizedDescription)
    87.8 +            Log.shared.errorAndCrash("%{public}@", error.localizedDescription)
    87.9              return nil
   87.10          }
   87.11      }
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/MessageModel/MessageModel/NetworkService/Util/jsonMimeType.txt	Mon May 20 16:30:04 2019 +0200
    88.3 @@ -0,0 +1,855 @@
    88.4 +{
    88.5 +"mimeType" : {
    88.6 +"" : "DEFAULT_ATTACHMENT_MIME_TYPE" ,
    88.7 +"k9s" : "K9_SETTINGS_MIME_TYPE",
    88.8 +"txt" : "text/plain",
    88.9 +"123" : "application/vnd.lotus-1-2-3",
   88.10 +"323" : "text/h323",
   88.11 +"3dml" : "text/vnd.in3d.3dml",
   88.12 +"3g2" : "video/3gpp2",
   88.13 +"3gp" : "video/3gpp",
   88.14 +"aab" : "application/x-authorware-bin",
   88.15 +"aac" : "audio/x-aac",
   88.16 +"aam" : "application/x-authorware-map",
   88.17 +"a" : "application/octet-stream",
   88.18 +"aas" : "application/x-authorware-seg",
   88.19 +"abw" : "application/x-abiword",
   88.20 +"acc" : "application/vnd.americandynamics.acc",
   88.21 +"ace" : "application/x-ace-compressed",
   88.22 +"acu" : "application/vnd.acucobol",
   88.23 +"acutc" : "application/vnd.acucorp",
   88.24 +"acx" : "application/internet-property-stream",
   88.25 +"adp" : "audio/adpcm",
   88.26 +"aep" : "application/vnd.audiograph",
   88.27 +"afm" : "application/x-font-type1",
   88.28 +"afp" : "application/vnd.ibm.modcap",
   88.29 +"ai" : "application/postscript",
   88.30 +"aif" : "audio/x-aiff",
   88.31 +"aifc" : "audio/x-aiff",
   88.32 +"aiff" : "audio/x-aiff",
   88.33 +"air" : "application/vnd.adobe.air-application-installer-package+zip",
   88.34 +"ami" : "application/vnd.amiga.ami",
   88.35 +"apk" : "application/vnd.android.package-archive",
   88.36 +"application" : "application/x-ms-application",
   88.37 +"apr" : "application/vnd.lotus-approach",
   88.38 +"asc" : "application/pgp-signature",
   88.39 +"asf" : "video/x-ms-asf",
   88.40 +"asm" : "text/x-asm",
   88.41 +"aso" : "application/vnd.accpac.simply.aso",
   88.42 +"asr" : "video/x-ms-asf",
   88.43 +"asx" : "video/x-ms-asf",
   88.44 +"atc" : "application/vnd.acucorp",
   88.45 +"atom" : "application/atom+xml",
   88.46 +"atomcat" : "application/atomcat+xml",
   88.47 +"atomsvc" : "application/atomsvc+xml",
   88.48 +"atx" : "application/vnd.antix.game-component",
   88.49 +"au" : "audio/basic",
   88.50 +"avi" : "video/x-msvideo",
   88.51 +"aw" : "application/applixware",
   88.52 +"axs" : "application/olescript",
   88.53 +"azf" : "application/vnd.airzip.filesecure.azf",
   88.54 +"azs" : "application/vnd.airzip.filesecure.azs",
   88.55 +"azw" : "application/vnd.amazon.ebook",
   88.56 +"bas" : "text/plain",
   88.57 +"bat" : "application/x-msdownload",
   88.58 +"bcpio" : "application/x-bcpio",
   88.59 +"bdf" : "application/x-font-bdf",
   88.60 +"bdm" : "application/vnd.syncml.dm+wbxml",
   88.61 +"bh2" : "application/vnd.fujitsu.oasysprs",
   88.62 +"bin" : "application/octet-stream",
   88.63 +"bmi" : "application/vnd.bmi",
   88.64 +"bmp" : "image/bmp",
   88.65 +"book" : "application/vnd.framemaker",
   88.66 +"box" : "application/vnd.previewsystems.box",
   88.67 +"boz" : "application/x-bzip2",
   88.68 +"bpk" : "application/octet-stream",
   88.69 +"btif" : "image/prs.btif",
   88.70 +"bz2" : "application/x-bzip2",
   88.71 +"bz" : "application/x-bzip",
   88.72 +"c4d" : "application/vnd.clonk.c4group",
   88.73 +"c4f" : "application/vnd.clonk.c4group",
   88.74 +"c4g" : "application/vnd.clonk.c4group",
   88.75 +"c4p" : "application/vnd.clonk.c4group",
   88.76 +"c4u" : "application/vnd.clonk.c4group",
   88.77 +"cab" : "application/vnd.ms-cab-compressed",
   88.78 +"car" : "application/vnd.curl.car",
   88.79 +"cat" : "application/vnd.ms-pki.seccat",
   88.80 +"cct" : "application/x-director",
   88.81 +"cc" : "text/x-c",
   88.82 +"ccxml" : "application/ccxml+xml",
   88.83 +"cdbcmsg" : "application/vnd.contact.cmsg",
   88.84 +"cdf" : "application/x-cdf",
   88.85 +"cdkey" : "application/vnd.mediastation.cdkey",
   88.86 +"cdx" : "chemical/x-cdx",
   88.87 +"cdxml" : "application/vnd.chemdraw+xml",
   88.88 +"cdy" : "application/vnd.cinderella",
   88.89 +"cer" : "application/x-x509-ca-cert",
   88.90 +"cgm" : "image/cgm",
   88.91 +"chat" : "application/x-chat",
   88.92 +"chm" : "application/vnd.ms-htmlhelp",
   88.93 +"chrt" : "application/vnd.kde.kchart",
   88.94 +"cif" : "chemical/x-cif",
   88.95 +"cii" : "application/vnd.anser-web-certificate-issue-initiation",
   88.96 +"cla" : "application/vnd.claymore",
   88.97 +"class" : "application/java-vm",
   88.98 +"clkk" : "application/vnd.crick.clicker.keyboard",
   88.99 +"clkp" : "application/vnd.crick.clicker.palette",
  88.100 +"clkt" : "application/vnd.crick.clicker.template",
  88.101 +"clkw" : "application/vnd.crick.clicker.wordbank",
  88.102 +"clkx" : "application/vnd.crick.clicker",
  88.103 +"clp" : "application/x-msclip",
  88.104 +"cmc" : "application/vnd.cosmocaller",
  88.105 +"cmdf" : "chemical/x-cmdf",
  88.106 +"cml" : "chemical/x-cml",
  88.107 +"cmp" : "application/vnd.yellowriver-custom-menu",
  88.108 +"cmx" : "image/x-cmx",
  88.109 +"cod" : "application/vnd.rim.cod",
  88.110 +"com" : "application/x-msdownload",
  88.111 +"conf" : "text/plain",
  88.112 +"cpio" : "application/x-cpio",
  88.113 +"cpp" : "text/x-c",
  88.114 +"cpt" : "application/mac-compactpro",
  88.115 +"crd" : "application/x-mscardfile",
  88.116 +"crl" : "application/pkix-crl",
  88.117 +"crt" : "application/x-x509-ca-cert",
  88.118 +"csh" : "application/x-csh",
  88.119 +"csml" : "chemical/x-csml",
  88.120 +"csp" : "application/vnd.commonspace",
  88.121 +"css" : "text/css",
  88.122 +"cst" : "application/x-director",
  88.123 +"csv" : "text/csv",
  88.124 +"c" : "text/plain",
  88.125 +"cu" : "application/cu-seeme",
  88.126 +"curl" : "text/vnd.curl",
  88.127 +"cww" : "application/prs.cww",
  88.128 +"cxt" : "application/x-director",
  88.129 +"cxx" : "text/x-c",
  88.130 +"daf" : "application/vnd.mobius.daf",
  88.131 +"dataless" : "application/vnd.fdsn.seed",
  88.132 +"davmount" : "application/davmount+xml",
  88.133 +"dcr" : "application/x-director",
  88.134 +"dcurl" : "text/vnd.curl.dcurl",
  88.135 +"dd2" : "application/vnd.oma.dd2+xml",
  88.136 +"ddd" : "application/vnd.fujixerox.ddd",
  88.137 +"deb" : "application/x-debian-package",
  88.138 +"def" : "text/plain",
  88.139 +"deploy" : "application/octet-stream",
  88.140 +"der" : "application/x-x509-ca-cert",
  88.141 +"dfac" : "application/vnd.dreamfactory",
  88.142 +"dic" : "text/x-c",
  88.143 +"diff" : "text/plain",
  88.144 +"dir" : "application/x-director",
  88.145 +"dis" : "application/vnd.mobius.dis",
  88.146 +"dist" : "application/octet-stream",
  88.147 +"distz" : "application/octet-stream",
  88.148 +"djv" : "image/vnd.djvu",
  88.149 +"djvu" : "image/vnd.djvu",
  88.150 +"dll" : "application/x-msdownload",
  88.151 +"dmg" : "application/octet-stream",
  88.152 +"dms" : "application/octet-stream",
  88.153 +"dna" : "application/vnd.dna",
  88.154 +"doc" : "application/msword",
  88.155 +"docm" : "application/vnd.ms-word.document.macroenabled.12",
  88.156 +"docx" : "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  88.157 +"dot" : "application/msword",
  88.158 +"dotm" : "application/vnd.ms-word.template.macroenabled.12",
  88.159 +"dotx" : "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
  88.160 +"dp" : "application/vnd.osgi.dp",
  88.161 +"dpg" : "application/vnd.dpgraph",
  88.162 +"dsc" : "text/prs.lines.tag",
  88.163 +"dtb" : "application/x-dtbook+xml",
  88.164 +"dtd" : "application/xml-dtd",
  88.165 +"dts" : "audio/vnd.dts",
  88.166 +"dtshd" : "audio/vnd.dts.hd",
  88.167 +"dump" : "application/octet-stream",
  88.168 +"dvi" : "application/x-dvi",
  88.169 +"dwf" : "model/vnd.dwf",
  88.170 +"dwg" : "image/vnd.dwg",
  88.171 +"dxf" : "image/vnd.dxf",
  88.172 +"dxp" : "application/vnd.spotfire.dxp",
  88.173 +"dxr" : "application/x-director",
  88.174 +"ecelp4800" : "audio/vnd.nuera.ecelp4800",
  88.175 +"ecelp7470" : "audio/vnd.nuera.ecelp7470",
  88.176 +"ecelp9600" : "audio/vnd.nuera.ecelp9600",
  88.177 +"ecma" : "application/ecmascript",
  88.178 +"edm" : "application/vnd.novadigm.edm",
  88.179 +"edx" : "application/vnd.novadigm.edx",
  88.180 +"efif" : "application/vnd.picsel",
  88.181 +"ei6" : "application/vnd.pg.osasli",
  88.182 +"elc" : "application/octet-stream",
  88.183 +"eml" : "message/rfc822",
  88.184 +"emma" : "application/emma+xml",
  88.185 +"eol" : "audio/vnd.digital-winds",
  88.186 +"eot" : "application/vnd.ms-fontobject",
  88.187 +"eps" : "application/postscript",
  88.188 +"epub" : "application/epub+zip",
  88.189 +"es3" : "application/vnd.eszigno3+xml",
  88.190 +"esf" : "application/vnd.epson.esf",
  88.191 +"espass" : "application/vnd.espass-espass+zip",
  88.192 +"et3" : "application/vnd.eszigno3+xml",
  88.193 +"etx" : "text/x-setext",
  88.194 +"evy" : "application/envoy",
  88.195 +"exe" : "application/octet-stream",
  88.196 +"ext" : "application/vnd.novadigm.ext",
  88.197 +"ez2" : "application/vnd.ezpix-album",
  88.198 +"ez3" : "application/vnd.ezpix-package",
  88.199 +"ez" : "application/andrew-inset",
  88.200 +"f4v" : "video/x-f4v",
  88.201 +"f77" : "text/x-fortran",
  88.202 +"f90" : "text/x-fortran",
  88.203 +"fbs" : "image/vnd.fastbidsheet",
  88.204 +"fdf" : "application/vnd.fdf",
  88.205 +"fe_launch" : "application/vnd.denovo.fcselayout-link",
  88.206 +"fg5" : "application/vnd.fujitsu.oasysgp",
  88.207 +"fgd" : "application/x-director",
  88.208 +"fh4" : "image/x-freehand",
  88.209 +"fh5" : "image/x-freehand",
  88.210 +"fh7" : "image/x-freehand",
  88.211 +"fhc" : "image/x-freehand",
  88.212 +"fh" : "image/x-freehand",
  88.213 +"fif" : "application/fractals",
  88.214 +"fig" : "application/x-xfig",
  88.215 +"fli" : "video/x-fli",
  88.216 +"flo" : "application/vnd.micrografx.flo",
  88.217 +"flr" : "x-world/x-vrml",
  88.218 +"flv" : "video/x-flv",
  88.219 +"flw" : "application/vnd.kde.kivio",
  88.220 +"flx" : "text/vnd.fmi.flexstor",
  88.221 +"fly" : "text/vnd.fly",
  88.222 +"fm" : "application/vnd.framemaker",
  88.223 +"fnc" : "application/vnd.frogans.fnc",
  88.224 +"for" : "text/x-fortran",
  88.225 +"fpx" : "image/vnd.fpx",
  88.226 +"frame" : "application/vnd.framemaker",
  88.227 +"fsc" : "application/vnd.fsc.weblaunch",
  88.228 +"fst" : "image/vnd.fst",
  88.229 +"ftc" : "application/vnd.fluxtime.clip",
  88.230 +"f" : "text/x-fortran",
  88.231 +"fti" : "application/vnd.anser-web-funds-transfer-initiation",
  88.232 +"fvt" : "video/vnd.fvt",
  88.233 +"fzs" : "application/vnd.fuzzysheet",
  88.234 +"g3" : "image/g3fax",
  88.235 +"gac" : "application/vnd.groove-account",
  88.236 +"gdl" : "model/vnd.gdl",
  88.237 +"geo" : "application/vnd.dynageo",
  88.238 +"gex" : "application/vnd.geometry-explorer",
  88.239 +"ggb" : "application/vnd.geogebra.file",
  88.240 +"ggt" : "application/vnd.geogebra.tool",
  88.241 +"ghf" : "application/vnd.groove-help",
  88.242 +"gif" : "image/gif",
  88.243 +"gim" : "application/vnd.groove-identity-message",
  88.244 +"gmx" : "application/vnd.gmx",
  88.245 +"gnumeric" : "application/x-gnumeric",
  88.246 +"gph" : "application/vnd.flographit",
  88.247 +"gqf" : "application/vnd.grafeq",
  88.248 +"gqs" : "application/vnd.grafeq",
  88.249 +"gram" : "application/srgs",
  88.250 +"gre" : "application/vnd.geometry-explorer",
  88.251 +"grv" : "application/vnd.groove-injector",
  88.252 +"grxml" : "application/srgs+xml",
  88.253 +"gsf" : "application/x-font-ghostscript",
  88.254 +"gtar" : "application/x-gtar",
  88.255 +"gtm" : "application/vnd.groove-tool-message",
  88.256 +"gtw" : "model/vnd.gtw",
  88.257 +"gv" : "text/vnd.graphviz",
  88.258 +"gz" : "application/x-gzip",
  88.259 +"h261" : "video/h261",
  88.260 +"h263" : "video/h263",
  88.261 +"h264" : "video/h264",
  88.262 +"hbci" : "application/vnd.hbci",
  88.263 +"hdf" : "application/x-hdf",
  88.264 +"hh" : "text/x-c",
  88.265 +"hlp" : "application/winhlp",
  88.266 +"hpgl" : "application/vnd.hp-hpgl",
  88.267 +"hpid" : "application/vnd.hp-hpid",
  88.268 +"hps" : "application/vnd.hp-hps",
  88.269 +"hqx" : "application/mac-binhex40",
  88.270 +"hta" : "application/hta",
  88.271 +"htc" : "text/x-component",
  88.272 +"h" : "text/plain",
  88.273 +"htke" : "application/vnd.kenameaapp",
  88.274 +"html" : "text/html",
  88.275 +"htm" : "text/html",
  88.276 +"htt" : "text/webviewhtml",
  88.277 +"hvd" : "application/vnd.yamaha.hv-dic",
  88.278 +"hvp" : "application/vnd.yamaha.hv-voice",
  88.279 +"hvs" : "application/vnd.yamaha.hv-script",
  88.280 +"icc" : "application/vnd.iccprofile",
  88.281 +"ice" : "x-conference/x-cooltalk",
  88.282 +"icm" : "application/vnd.iccprofile",
  88.283 +"ico" : "image/x-icon",
  88.284 +"ics" : "text/calendar",
  88.285 +"ief" : "image/ief",
  88.286 +"ifb" : "text/calendar",
  88.287 +"ifm" : "application/vnd.shana.informed.formdata",
  88.288 +"iges" : "model/iges",
  88.289 +"igl" : "application/vnd.igloader",
  88.290 +"igs" : "model/iges",
  88.291 +"igx" : "application/vnd.micrografx.igx",
  88.292 +"iif" : "application/vnd.shana.informed.interchange",
  88.293 +"iii" : "application/x-iphone",
  88.294 +"imp" : "application/vnd.accpac.simply.imp",
  88.295 +"ims" : "application/vnd.ms-ims",
  88.296 +"ins" : "application/x-internet-signup",
  88.297 +"in" : "text/plain",
  88.298 +"ipk" : "application/vnd.shana.informed.package",
  88.299 +"irm" : "application/vnd.ibm.rights-management",
  88.300 +"irp" : "application/vnd.irepository.package+xml",
  88.301 +"iso" : "application/octet-stream",
  88.302 +"isp" : "application/x-internet-signup",
  88.303 +"itp" : "application/vnd.shana.informed.formtemplate",
  88.304 +"ivp" : "application/vnd.immervision-ivp",
  88.305 +"ivu" : "application/vnd.immervision-ivu",
  88.306 +"jad" : "text/vnd.sun.j2me.app-descriptor",
  88.307 +"jam" : "application/vnd.jam",
  88.308 +"jar" : "application/java-archive",
  88.309 +"java" : "text/x-java-source",
  88.310 +"jfif" : "image/pipeg",
  88.311 +"jisp" : "application/vnd.jisp",
  88.312 +"jlt" : "application/vnd.hp-jlyt",
  88.313 +"jnlp" : "application/x-java-jnlp-file",
  88.314 +"joda" : "application/vnd.joost.joda-archive",
  88.315 +"jpeg" : "image/jpeg",
  88.316 +"jpe" : "image/jpeg",
  88.317 +"jpg" : "image/jpeg",
  88.318 +"jpgm" : "video/jpm",
  88.319 +"jpgv" : "video/jpeg",
  88.320 +"jpm" : "video/jpm",
  88.321 +"js" : "application/x-javascript",
  88.322 +"json" : "application/json",
  88.323 +"kar" : "audio/midi",
  88.324 +"karbon" : "application/vnd.kde.karbon",
  88.325 +"kfo" : "application/vnd.kde.kformula",
  88.326 +"kia" : "application/vnd.kidspiration",
  88.327 +"kil" : "application/x-killustrator",
  88.328 +"kml" : "application/vnd.google-earth.kml+xml",
  88.329 +"kmz" : "application/vnd.google-earth.kmz",
  88.330 +"kne" : "application/vnd.kinar",
  88.331 +"knp" : "application/vnd.kinar",
  88.332 +"kon" : "application/vnd.kde.kontour",
  88.333 +"kpr" : "application/vnd.kde.kpresenter",
  88.334 +"kpt" : "application/vnd.kde.kpresenter",
  88.335 +"ksh" : "text/plain",
  88.336 +"ksp" : "application/vnd.kde.kspread",
  88.337 +"ktr" : "application/vnd.kahootz",
  88.338 +"ktz" : "application/vnd.kahootz",
  88.339 +"kwd" : "application/vnd.kde.kword",
  88.340 +"kwt" : "application/vnd.kde.kword",
  88.341 +"latex" : "application/x-latex",
  88.342 +"lbd" : "application/vnd.llamagraphics.life-balance.desktop",
  88.343 +"lbe" : "application/vnd.llamagraphics.life-balance.exchange+xml",
  88.344 +"les" : "application/vnd.hhe.lesson-player",
  88.345 +"lha" : "application/octet-stream",
  88.346 +"link66" : "application/vnd.route66.link66+xml",
  88.347 +"list3820" : "application/vnd.ibm.modcap",
  88.348 +"listafp" : "application/vnd.ibm.modcap",
  88.349 +"list" : "text/plain",
  88.350 +"log" : "text/plain",
  88.351 +"lostxml" : "application/lost+xml",
  88.352 +"lrf" : "application/octet-stream",
  88.353 +"lrm" : "application/vnd.ms-lrm",
  88.354 +"lsf" : "video/x-la-asf",
  88.355 +"lsx" : "video/x-la-asf",
  88.356 +"ltf" : "application/vnd.frogans.ltf",
  88.357 +"lvp" : "audio/vnd.lucent.voice",
  88.358 +"lwp" : "application/vnd.lotus-wordpro",
  88.359 +"lzh" : "application/octet-stream",
  88.360 +"m13" : "application/x-msmediaview",
  88.361 +"m14" : "application/x-msmediaview",
  88.362 +"m1v" : "video/mpeg",
  88.363 +"m2a" : "audio/mpeg",
  88.364 +"m2v" : "video/mpeg",
  88.365 +"m3a" : "audio/mpeg",
  88.366 +"m3u" : "audio/x-mpegurl",
  88.367 +"m4u" : "video/vnd.mpegurl",
  88.368 +"m4v" : "video/x-m4v",
  88.369 +"ma" : "application/mathematica",
  88.370 +"mag" : "application/vnd.ecowin.chart",
  88.371 +"maker" : "application/vnd.framemaker",
  88.372 +"man" : "text/troff",
  88.373 +"mathml" : "application/mathml+xml",
  88.374 +"mb" : "application/mathematica",
  88.375 +"mbk" : "application/vnd.mobius.mbk",
  88.376 +"mbox" : "application/mbox",
  88.377 +"mc1" : "application/vnd.medcalcdata",
  88.378 +"mcd" : "application/vnd.mcd",
  88.379 +"mcurl" : "text/vnd.curl.mcurl",
  88.380 +"mdb" : "application/x-msaccess",
  88.381 +"mdi" : "image/vnd.ms-modi",
  88.382 +"mesh" : "model/mesh",
  88.383 +"me" : "text/troff",
  88.384 +"mfm" : "application/vnd.mfmp",
  88.385 +"mgz" : "application/vnd.proteus.magazine",
  88.386 +"mht" : "message/rfc822",
  88.387 +"mhtml" : "message/rfc822",
  88.388 +"mid" : "audio/midi",
  88.389 +"midi" : "audio/midi",
  88.390 +"mif" : "application/vnd.mif",
  88.391 +"mime" : "message/rfc822",
  88.392 +"mj2" : "video/mj2",
  88.393 +"mjp2" : "video/mj2",
  88.394 +"mlp" : "application/vnd.dolby.mlp",
  88.395 +"mmd" : "application/vnd.chipnuts.karaoke-mmd",
  88.396 +"mmf" : "application/vnd.smaf",
  88.397 +"mmr" : "image/vnd.fujixerox.edmics-mmr",
  88.398 +"mny" : "application/x-msmoney",
  88.399 +"mobi" : "application/x-mobipocket-ebook",
  88.400 +"movie" : "video/x-sgi-movie",
  88.401 +"mov" : "video/quicktime",
  88.402 +"mp2a" : "audio/mpeg",
  88.403 +"mp2" : "video/mpeg",
  88.404 +"mp3" : "audio/mpeg",
  88.405 +"mp4a" : "audio/mp4",
  88.406 +"mp4s" : "application/mp4",
  88.407 +"mp4" : "video/mp4",
  88.408 +"mp4v" : "video/mp4",
  88.409 +"mpa" : "video/mpeg",
  88.410 +"mpc" : "application/vnd.mophun.certificate",
  88.411 +"mpeg" : "video/mpeg",
  88.412 +"mpe" : "video/mpeg",
  88.413 +"mpg4" : "video/mp4",
  88.414 +"mpga" : "audio/mpeg",
  88.415 +"mpg" : "video/mpeg",
  88.416 +"mpkg" : "application/vnd.apple.installer+xml",
  88.417 +"mpm" : "application/vnd.blueice.multipass",
  88.418 +"mpn" : "application/vnd.mophun.application",
  88.419 +"mpp" : "application/vnd.ms-project",
  88.420 +"mpt" : "application/vnd.ms-project",
  88.421 +"mpv2" : "video/mpeg",
  88.422 +"mpy" : "application/vnd.ibm.minipay",
  88.423 +"mqy" : "application/vnd.mobius.mqy",
  88.424 +"mrc" : "application/marc",
  88.425 +"mscml" : "application/mediaservercontrol+xml",
  88.426 +"mseed" : "application/vnd.fdsn.mseed",
  88.427 +"mseq" : "application/vnd.mseq",
  88.428 +"msf" : "application/vnd.epson.msf",
  88.429 +"msh" : "model/mesh",
  88.430 +"msi" : "application/x-msdownload",
  88.431 +"ms" : "text/troff",
  88.432 +"msty" : "application/vnd.muvee.style",
  88.433 +"mts" : "model/vnd.mts",
  88.434 +"mus" : "application/vnd.musician",
  88.435 +"musicxml" : "application/vnd.recordare.musicxml+xml",
  88.436 +"mvb" : "application/x-msmediaview",
  88.437 +"mxf" : "application/mxf",
  88.438 +"mxl" : "application/vnd.recordare.musicxml",
  88.439 +"mxml" : "application/xv+xml",
  88.440 +"mxs" : "application/vnd.triscape.mxs",
  88.441 +"mxu" : "video/vnd.mpegurl",
  88.442 +"nb" : "application/mathematica",
  88.443 +"nc" : "application/x-netcdf",
  88.444 +"ncx" : "application/x-dtbncx+xml",
  88.445 +"n-gage" : "application/vnd.nokia.n-gage.symbian.install",
  88.446 +"ngdat" : "application/vnd.nokia.n-gage.data",
  88.447 +"nlu" : "application/vnd.neurolanguage.nlu",
  88.448 +"nml" : "application/vnd.enliven",
  88.449 +"nnd" : "application/vnd.noblenet-directory",
  88.450 +"nns" : "application/vnd.noblenet-sealer",
  88.451 +"nnw" : "application/vnd.noblenet-web",
  88.452 +"npx" : "image/vnd.net-fpx",
  88.453 +"nsf" : "application/vnd.lotus-notes",
  88.454 +"nws" : "message/rfc822",
  88.455 +"oa2" : "application/vnd.fujitsu.oasys2",
  88.456 +"oa3" : "application/vnd.fujitsu.oasys3",
  88.457 +"o" : "application/octet-stream",
  88.458 +"oas" : "application/vnd.fujitsu.oasys",
  88.459 +"obd" : "application/x-msbinder",
  88.460 +"obj" : "application/octet-stream",
  88.461 +"oda" : "application/oda",
  88.462 +"odb" : "application/vnd.oasis.opendocument.database",
  88.463 +"odc" : "application/vnd.oasis.opendocument.chart",
  88.464 +"odf" : "application/vnd.oasis.opendocument.formula",
  88.465 +"odft" : "application/vnd.oasis.opendocument.formula-template",
  88.466 +"odg" : "application/vnd.oasis.opendocument.graphics",
  88.467 +"odi" : "application/vnd.oasis.opendocument.image",
  88.468 +"odp" : "application/vnd.oasis.opendocument.presentation",
  88.469 +"ods" : "application/vnd.oasis.opendocument.spreadsheet",
  88.470 +"odt" : "application/vnd.oasis.opendocument.text",
  88.471 +"oga" : "audio/ogg",
  88.472 +"ogg" : "audio/ogg",
  88.473 +"ogv" : "video/ogg",
  88.474 +"ogx" : "application/ogg",
  88.475 +"onepkg" : "application/onenote",
  88.476 +"onetmp" : "application/onenote",
  88.477 +"onetoc2" : "application/onenote",
  88.478 +"onetoc" : "application/onenote",
  88.479 +"opf" : "application/oebps-package+xml",
  88.480 +"oprc" : "application/vnd.palm",
  88.481 +"org" : "application/vnd.lotus-organizer",
  88.482 +"osf" : "application/vnd.yamaha.openscoreformat",
  88.483 +"osfpvg" : "application/vnd.yamaha.openscoreformat.osfpvg+xml",
  88.484 +"otc" : "application/vnd.oasis.opendocument.chart-template",
  88.485 +"otf" : "application/x-font-otf",
  88.486 +"otg" : "application/vnd.oasis.opendocument.graphics-template",
  88.487 +"oth" : "application/vnd.oasis.opendocument.text-web",
  88.488 +"oti" : "application/vnd.oasis.opendocument.image-template",
  88.489 +"otm" : "application/vnd.oasis.opendocument.text-master",
  88.490 +"otp" : "application/vnd.oasis.opendocument.presentation-template",
  88.491 +"ots" : "application/vnd.oasis.opendocument.spreadsheet-template",
  88.492 +"ott" : "application/vnd.oasis.opendocument.text-template",
  88.493 +"oxt" : "application/vnd.openofficeorg.extension",
  88.494 +"p10" : "application/pkcs10",
  88.495 +"p12" : "application/x-pkcs12",
  88.496 +"p7b" : "application/x-pkcs7-certificates",
  88.497 +"p7c" : "application/x-pkcs7-mime",
  88.498 +"p7m" : "application/x-pkcs7-mime",
  88.499 +"p7r" : "application/x-pkcs7-certreqresp",
  88.500 +"p7s" : "application/x-pkcs7-signature",
  88.501 +"pas" : "text/x-pascal",
  88.502 +"pbd" : "application/vnd.powerbuilder6",
  88.503 +"pbm" : "image/x-portable-bitmap",
  88.504 +"pcf" : "application/x-font-pcf",
  88.505 +"pcl" : "application/vnd.hp-pcl",
  88.506 +"pclxl" : "application/vnd.hp-pclxl",
  88.507 +"pct" : "image/x-pict",
  88.508 +"pcurl" : "application/vnd.curl.pcurl",
  88.509 +"pcx" : "image/x-pcx",
  88.510 +"pdb" : "application/vnd.palm",
  88.511 +"pdf" : "application/pdf",
  88.512 +"pfa" : "application/x-font-type1",
  88.513 +"pfb" : "application/x-font-type1",
  88.514 +"pfm" : "application/x-font-type1",
  88.515 +"pfr" : "application/font-tdpfr",
  88.516 +"pfx" : "application/x-pkcs12",
  88.517 +"pgm" : "image/x-portable-graymap",
  88.518 +"pgn" : "application/x-chess-pgn",
  88.519 +"pgp" : "application/pgp-encrypted",
  88.520 +"pic" : "image/x-pict",
  88.521 +"pkg" : "application/octet-stream",
  88.522 +"pki" : "application/pkixcmp",
  88.523 +"pkipath" : "application/pkix-pkipath",
  88.524 +"pkpass" : "application/vnd-com.apple.pkpass",
  88.525 +"pko" : "application/ynd.ms-pkipko",
  88.526 +"plb" : "application/vnd.3gpp.pic-bw-large",
  88.527 +"plc" : "application/vnd.mobius.plc",
  88.528 +"plf" : "application/vnd.pocketlearn",
  88.529 +"pls" : "application/pls+xml",
  88.530 +"pl" : "text/plain",
  88.531 +"pma" : "application/x-perfmon",
  88.532 +"pmc" : "application/x-perfmon",
  88.533 +"pml" : "application/x-perfmon",
  88.534 +"pmr" : "application/x-perfmon",
  88.535 +"pmw" : "application/x-perfmon",
  88.536 +"png" : "image/png",
  88.537 +"pnm" : "image/x-portable-anymap",
  88.538 +"portpkg" : "application/vnd.macports.portpkg",
  88.539 +"pot," : "application/vnd.ms-powerpoint",
  88.540 +"pot" : "application/vnd.ms-powerpoint",
  88.541 +"potm" : "application/vnd.ms-powerpoint.template.macroenabled.12",
  88.542 +"potx" : "application/vnd.openxmlformats-officedocument.presentationml.template",
  88.543 +"ppa" : "application/vnd.ms-powerpoint",
  88.544 +"ppam" : "application/vnd.ms-powerpoint.addin.macroenabled.12",
  88.545 +"ppd" : "application/vnd.cups-ppd",
  88.546 +"ppm" : "image/x-portable-pixmap",
  88.547 +"pps" : "application/vnd.ms-powerpoint",
  88.548 +"ppsm" : "application/vnd.ms-powerpoint.slideshow.macroenabled.12",
  88.549 +"ppsx" : "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
  88.550 +"ppt" : "application/vnd.ms-powerpoint",
  88.551 +"pptm" : "application/vnd.ms-powerpoint.presentation.macroenabled.12",
  88.552 +"pptx" : "application/vnd.openxmlformats-officedocument.presentationml.presentation",
  88.553 +"pqa" : "application/vnd.palm",
  88.554 +"prc" : "application/x-mobipocket-ebook",
  88.555 +"pre" : "application/vnd.lotus-freelance",
  88.556 +"prf" : "application/pics-rules",
  88.557 +"ps" : "application/postscript",
  88.558 +"psb" : "application/vnd.3gpp.pic-bw-small",
  88.559 +"psd" : "image/vnd.adobe.photoshop",
  88.560 +"psf" : "application/x-font-linux-psf",
  88.561 +"p" : "text/x-pascal",
  88.562 +"ptid" : "application/vnd.pvi.ptid1",
  88.563 +"pub" : "application/x-mspublisher",
  88.564 +"pvb" : "application/vnd.3gpp.pic-bw-var",
  88.565 +"pwn" : "application/vnd.3m.post-it-notes",
  88.566 +"pwz" : "application/vnd.ms-powerpoint",
  88.567 +"pya" : "audio/vnd.ms-playready.media.pya",
  88.568 +"pyc" : "application/x-python-code",
  88.569 +"pyo" : "application/x-python-code",
  88.570 +"py" : "text/x-python",
  88.571 +"pyv" : "video/vnd.ms-playready.media.pyv",
  88.572 +"qam" : "application/vnd.epson.quickanime",
  88.573 +"qbo" : "application/vnd.intu.qbo",
  88.574 +"qfx" : "application/vnd.intu.qfx",
  88.575 +"qps" : "application/vnd.publishare-delta-tree",
  88.576 +"qt" : "video/quicktime",
  88.577 +"qwd" : "application/vnd.quark.quarkxpress",
  88.578 +"qwt" : "application/vnd.quark.quarkxpress",
  88.579 +"qxb" : "application/vnd.quark.quarkxpress",
  88.580 +"qxd" : "application/vnd.quark.quarkxpress",
  88.581 +"qxl" : "application/vnd.quark.quarkxpress",
  88.582 +"qxt" : "application/vnd.quark.quarkxpress",
  88.583 +"ra" : "audio/x-pn-realaudio",
  88.584 +"ram" : "audio/x-pn-realaudio",
  88.585 +"rar" : "application/x-rar-compressed",
  88.586 +"ras" : "image/x-cmu-raster",
  88.587 +"rcprofile" : "application/vnd.ipunplugged.rcprofile",
  88.588 +"rdf" : "application/rdf+xml",
  88.589 +"rdz" : "application/vnd.data-vision.rdz",
  88.590 +"rep" : "application/vnd.businessobjects",
  88.591 +"res" : "application/x-dtbresource+xml",
  88.592 +"rgb" : "image/x-rgb",
  88.593 +"rif" : "application/reginfo+xml",
  88.594 +"rl" : "application/resource-lists+xml",
  88.595 +"rlc" : "image/vnd.fujixerox.edmics-rlc",
  88.596 +"rld" : "application/resource-lists-diff+xml",
  88.597 +"rm" : "application/vnd.rn-realmedia",
  88.598 +"rmi" : "audio/midi",
  88.599 +"rmp" : "audio/x-pn-realaudio-plugin",
  88.600 +"rms" : "application/vnd.jcp.javame.midlet-rms",
  88.601 +"rnc" : "application/relax-ng-compact-syntax",
  88.602 +"roff" : "text/troff",
  88.603 +"rpm" : "application/x-rpm",
  88.604 +"rpss" : "application/vnd.nokia.radio-presets",
  88.605 +"rpst" : "application/vnd.nokia.radio-preset",
  88.606 +"rq" : "application/sparql-query",
  88.607 +"rs" : "application/rls-services+xml",
  88.608 +"rsd" : "application/rsd+xml",
  88.609 +"rss" : "application/rss+xml",
  88.610 +"rtf" : "application/rtf",
  88.611 +"rtx" : "text/richtext",
  88.612 +"saf" : "application/vnd.yamaha.smaf-audio",
  88.613 +"sbml" : "application/sbml+xml",
  88.614 +"sc" : "application/vnd.ibm.secure-container",
  88.615 +"scd" : "application/x-msschedule",
  88.616 +"scm" : "application/vnd.lotus-screencam",
  88.617 +"scq" : "application/scvp-cv-request",
  88.618 +"scs" : "application/scvp-cv-response",
  88.619 +"sct" : "text/scriptlet",
  88.620 +"scurl" : "text/vnd.curl.scurl",
  88.621 +"sda" : "application/vnd.stardivision.draw",
  88.622 +"sdc" : "application/vnd.stardivision.calc",
  88.623 +"sdd" : "application/vnd.stardivision.impress",
  88.624 +"sdkd" : "application/vnd.solent.sdkm+xml",
  88.625 +"sdkm" : "application/vnd.solent.sdkm+xml",
  88.626 +"sdp" : "application/sdp",
  88.627 +"sdw" : "application/vnd.stardivision.writer",
  88.628 +"see" : "application/vnd.seemail",
  88.629 +"seed" : "application/vnd.fdsn.seed",
  88.630 +"sema" : "application/vnd.sema",
  88.631 +"semd" : "application/vnd.semd",
  88.632 +"semf" : "application/vnd.semf",
  88.633 +"ser" : "application/java-serialized-object",
  88.634 +"setpay" : "application/set-payment-initiation",
  88.635 +"setreg" : "application/set-registration-initiation",
  88.636 +"sfd-hdstx" : "application/vnd.hydrostatix.sof-data",
  88.637 +"sfs" : "application/vnd.spotfire.sfs",
  88.638 +"sgl" : "application/vnd.stardivision.writer-global",
  88.639 +"sgml" : "text/sgml",
  88.640 +"sgm" : "text/sgml",
  88.641 +"sh" : "application/x-sh",
  88.642 +"shar" : "application/x-shar",
  88.643 +"shf" : "application/shf+xml",
  88.644 +"sic" : "application/vnd.wap.sic",
  88.645 +"sig" : "application/pgp-signature",
  88.646 +"silo" : "model/mesh",
  88.647 +"sis" : "application/vnd.symbian.install",
  88.648 +"sisx" : "application/vnd.symbian.install",
  88.649 +"sit" : "application/x-stuffit",
  88.650 +"si" : "text/vnd.wap.si",
  88.651 +"sitx" : "application/x-stuffitx",
  88.652 +"skd" : "application/vnd.koan",
  88.653 +"skm" : "application/vnd.koan",
  88.654 +"skp" : "application/vnd.koan",
  88.655 +"skt" : "application/vnd.koan",
  88.656 +"slc" : "application/vnd.wap.slc",
  88.657 +"sldm" : "application/vnd.ms-powerpoint.slide.macroenabled.12",
  88.658 +"sldx" : "application/vnd.openxmlformats-officedocument.presentationml.slide",
  88.659 +"slt" : "application/vnd.epson.salt",
  88.660 +"sl" : "text/vnd.wap.sl",
  88.661 +"smf" : "application/vnd.stardivision.math",
  88.662 +"smi" : "application/smil+xml",
  88.663 +"smil" : "application/smil+xml",
  88.664 +"snd" : "audio/basic",
  88.665 +"snf" : "application/x-font-snf",
  88.666 +"so" : "application/octet-stream",
  88.667 +"spc" : "application/x-pkcs7-certificates",
  88.668 +"spf" : "application/vnd.yamaha.smaf-phrase",
  88.669 +"spl" : "application/x-futuresplash",
  88.670 +"spot" : "text/vnd.in3d.spot",
  88.671 +"spp" : "application/scvp-vp-response",
  88.672 +"spq" : "application/scvp-vp-request",
  88.673 +"spx" : "audio/ogg",
  88.674 +"src" : "application/x-wais-source",
  88.675 +"srx" : "application/sparql-results+xml",
  88.676 +"sse" : "application/vnd.kodak-descriptor",
  88.677 +"ssf" : "application/vnd.epson.ssf",
  88.678 +"ssml" : "application/ssml+xml",
  88.679 +"sst" : "application/vnd.ms-pkicertstore",
  88.680 +"stc" : "application/vnd.sun.xml.calc.template",
  88.681 +"std" : "application/vnd.sun.xml.draw.template",
  88.682 +"s" : "text/x-asm",
  88.683 +"stf" : "application/vnd.wt.stf",
  88.684 +"sti" : "application/vnd.sun.xml.impress.template",
  88.685 +"stk" : "application/hyperstudio",
  88.686 +"stl" : "application/vnd.ms-pki.stl",
  88.687 +"stm" : "text/html",
  88.688 +"str" : "application/vnd.pg.format",
  88.689 +"stw" : "application/vnd.sun.xml.writer.template",
  88.690 +"sus" : "application/vnd.sus-calendar",
  88.691 +"susp" : "application/vnd.sus-calendar",
  88.692 +"sv4cpio" : "application/x-sv4cpio",
  88.693 +"sv4crc" : "application/x-sv4crc",
  88.694 +"svd" : "application/vnd.svd",
  88.695 +"svg" : "image/svg+xml",
  88.696 +"svgz" : "image/svg+xml",
  88.697 +"swa" : "application/x-director",
  88.698 +"swf" : "application/x-shockwave-flash",
  88.699 +"swi" : "application/vnd.arastra.swi",
  88.700 +"sxc" : "application/vnd.sun.xml.calc",
  88.701 +"sxd" : "application/vnd.sun.xml.draw",
  88.702 +"sxg" : "application/vnd.sun.xml.writer.global",
  88.703 +"sxi" : "application/vnd.sun.xml.impress",
  88.704 +"sxm" : "application/vnd.sun.xml.math",
  88.705 +"sxw" : "application/vnd.sun.xml.writer",
  88.706 +"tao" : "application/vnd.tao.intent-module-archive",
  88.707 +"t" : "application/x-troff",
  88.708 +"tar" : "application/x-tar",
  88.709 +"tcap" : "application/vnd.3gpp2.tcap",
  88.710 +"tcl" : "application/x-tcl",
  88.711 +"teacher" : "application/vnd.smart.teacher",
  88.712 +"tex" : "application/x-tex",
  88.713 +"texi" : "application/x-texinfo",
  88.714 +"texinfo" : "application/x-texinfo",
  88.715 +"text" : "text/plain",
  88.716 +"tfm" : "application/x-tex-tfm",
  88.717 +"tgz" : "application/x-gzip",
  88.718 +"tiff" : "image/tiff",
  88.719 +"tif" : "image/tiff",
  88.720 +"tmo" : "application/vnd.tmobile-livetv",
  88.721 +"torrent" : "application/x-bittorrent",
  88.722 +"tpl" : "application/vnd.groove-tool-template",
  88.723 +"tpt" : "application/vnd.trid.tpt",
  88.724 +"tra" : "application/vnd.trueapp",
  88.725 +"trm" : "application/x-msterminal",
  88.726 +"tr" : "text/troff",
  88.727 +"tsv" : "text/tab-separated-values",
  88.728 +"ttc" : "application/x-font-ttf",
  88.729 +"ttf" : "application/x-font-ttf",
  88.730 +"twd" : "application/vnd.simtech-mindmapper",
  88.731 +"twds" : "application/vnd.simtech-mindmapper",
  88.732 +"txd" : "application/vnd.genomatix.tuxedo",
  88.733 +"txf" : "application/vnd.mobius.txf",
  88.734 +"txt" : "text/plain",
  88.735 +"u32" : "application/x-authorware-bin",
  88.736 +"udeb" : "application/x-debian-package",
  88.737 +"ufd" : "application/vnd.ufdl",
  88.738 +"ufdl" : "application/vnd.ufdl",
  88.739 +"uls" : "text/iuls",
  88.740 +"umj" : "application/vnd.umajin",
  88.741 +"unityweb" : "application/vnd.unity",
  88.742 +"uoml" : "application/vnd.uoml+xml",
  88.743 +"uris" : "text/uri-list",
  88.744 +"uri" : "text/uri-list",
  88.745 +"urls" : "text/uri-list",
  88.746 +"ustar" : "application/x-ustar",
  88.747 +"utz" : "application/vnd.uiq.theme",
  88.748 +"uu" : "text/x-uuencode",
  88.749 +"vcd" : "application/x-cdlink",
  88.750 +"vcf" : "text/x-vcard",
  88.751 +"vcg" : "application/vnd.groove-vcard",
  88.752 +"vcs" : "text/x-vcalendar",
  88.753 +"vcx" : "application/vnd.vcx",
  88.754 +"vis" : "application/vnd.visionary",
  88.755 +"viv" : "video/vnd.vivo",
  88.756 +"vor" : "application/vnd.stardivision.writer",
  88.757 +"vox" : "application/x-authorware-bin",
  88.758 +"vrml" : "x-world/x-vrml",
  88.759 +"vsd" : "application/vnd.visio",
  88.760 +"vsf" : "application/vnd.vsf",
  88.761 +"vss" : "application/vnd.visio",
  88.762 +"vst" : "application/vnd.visio",
  88.763 +"vsw" : "application/vnd.visio",
  88.764 +"vtu" : "model/vnd.vtu",
  88.765 +"vxml" : "application/voicexml+xml",
  88.766 +"w3d" : "application/x-director",
  88.767 +"wad" : "application/x-doom",
  88.768 +"wav" : "audio/x-wav",
  88.769 +"wax" : "audio/x-ms-wax",
  88.770 +"wbmp" : "image/vnd.wap.wbmp",
  88.771 +"wbs" : "application/vnd.criticaltools.wbs+xml",
  88.772 +"wbxml" : "application/vnd.wap.wbxml",
  88.773 +"wcm" : "application/vnd.ms-works",
  88.774 +"wdb" : "application/vnd.ms-works",
  88.775 +"wiz" : "application/msword",
  88.776 +"wks" : "application/vnd.ms-works",
  88.777 +"wma" : "audio/x-ms-wma",
  88.778 +"wmd" : "application/x-ms-wmd",
  88.779 +"wmf" : "application/x-msmetafile",
  88.780 +"wmlc" : "application/vnd.wap.wmlc",
  88.781 +"wmlsc" : "application/vnd.wap.wmlscriptc",
  88.782 +"wmls" : "text/vnd.wap.wmlscript",
  88.783 +"wml" : "text/vnd.wap.wml",
  88.784 +"wm" : "video/x-ms-wm",
  88.785 +"wmv" : "video/x-ms-wmv",
  88.786 +"wmx" : "video/x-ms-wmx",
  88.787 +"wmz" : "application/x-ms-wmz",
  88.788 +"wpd" : "application/vnd.wordperfect",
  88.789 +"wpl" : "application/vnd.ms-wpl",
  88.790 +"wps" : "application/vnd.ms-works",
  88.791 +"wqd" : "application/vnd.wqd",
  88.792 +"wri" : "application/x-mswrite",
  88.793 +"wrl" : "x-world/x-vrml",
  88.794 +"wrz" : "x-world/x-vrml",
  88.795 +"wsdl" : "application/wsdl+xml",
  88.796 +"wspolicy" : "application/wspolicy+xml",
  88.797 +"wtb" : "application/vnd.webturbo",
  88.798 +"wvx" : "video/x-ms-wvx",
  88.799 +"x32" : "application/x-authorware-bin",
  88.800 +"x3d" : "application/vnd.hzn-3d-crossword",
  88.801 +"xaf" : "x-world/x-vrml",
  88.802 +"xap" : "application/x-silverlight-app",
  88.803 +"xar" : "application/vnd.xara",
  88.804 +"xbap" : "application/x-ms-xbap",
  88.805 +"xbd" : "application/vnd.fujixerox.docuworks.binder",
  88.806 +"xbm" : "image/x-xbitmap",
  88.807 +"xdm" : "application/vnd.syncml.dm+xml",
  88.808 +"xdp" : "application/vnd.adobe.xdp+xml",
  88.809 +"xdw" : "application/vnd.fujixerox.docuworks",
  88.810 +"xenc" : "application/xenc+xml",
  88.811 +"xer" : "application/patch-ops-error+xml",
  88.812 +"xfdf" : "application/vnd.adobe.xfdf",
  88.813 +"xfdl" : "application/vnd.xfdl",
  88.814 +"xht" : "application/xhtml+xml",
  88.815 +"xhtml" : "application/xhtml+xml",
  88.816 +"xhvml" : "application/xv+xml",
  88.817 +"xif" : "image/vnd.xiff",
  88.818 +"xla" : "application/vnd.ms-excel",
  88.819 +"xlam" : "application/vnd.ms-excel.addin.macroenabled.12",
  88.820 +"xlb" : "application/vnd.ms-excel",
  88.821 +"xlc" : "application/vnd.ms-excel",
  88.822 +"xlm" : "application/vnd.ms-excel",
  88.823 +"xls" : "application/vnd.ms-excel",
  88.824 +"xlsb" : "application/vnd.ms-excel.sheet.binary.macroenabled.12",
  88.825 +"xlsm" : "application/vnd.ms-excel.sheet.macroenabled.12",
  88.826 +"xlsx" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  88.827 +"xlt" : "application/vnd.ms-excel",
  88.828 +"xltm" : "application/vnd.ms-excel.template.macroenabled.12",
  88.829 +"xltx" : "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
  88.830 +"xlw" : "application/vnd.ms-excel",
  88.831 +"xml" : "application/xml",
  88.832 +"xo" : "application/vnd.olpc-sugar",
  88.833 +"xof" : "x-world/x-vrml",
  88.834 +"xop" : "application/xop+xml",
  88.835 +"xpdl" : "application/xml",
  88.836 +"xpi" : "application/x-xpinstall",
  88.837 +"xpm" : "image/x-xpixmap",
  88.838 +"xpr" : "application/vnd.is-xpr",
  88.839 +"xps" : "application/vnd.ms-xpsdocument",
  88.840 +"xpw" : "application/vnd.intercon.formnet",
  88.841 +"xpx" : "application/vnd.intercon.formnet",
  88.842 +"xsl" : "application/xml",
  88.843 +"xslt" : "application/xslt+xml",
  88.844 +"xsm" : "application/vnd.syncml+xml",
  88.845 +"xspf" : "application/xspf+xml",
  88.846 +"xul" : "application/vnd.mozilla.xul+xml",
  88.847 +"xvm" : "application/xv+xml",
  88.848 +"xvml" : "application/xv+xml",
  88.849 +"xwd" : "image/x-xwindowdump",
  88.850 +"xyz" : "chemical/x-xyz",
  88.851 +"z" : "application/x-compress",
  88.852 +"zaz" : "application/vnd.zzazz.deck+xml",
  88.853 +"zip" : "application/zip",
  88.854 +"zir" : "application/vnd.zul",
  88.855 +"zirz" : "application/vnd.zul",
  88.856 +"zmm" : "application/vnd.handheld-entertainment+xml"
  88.857 +}
  88.858 +}
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/MessageModel/MessageModel/NetworkService/VerifiableAccount/BasicConnectInfo+VerifiableAccount.swift	Mon May 20 16:30:04 2019 +0200
    89.3 @@ -0,0 +1,48 @@
    89.4 +//
    89.5 +//  BasicConnectInfo+VerifiableAccount.swift
    89.6 +//  pEp
    89.7 +//
    89.8 +//  Created by Dirk Zimmermann on 16.04.19.
    89.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   89.10 +//
   89.11 +
   89.12 +import Foundation
   89.13 +
   89.14 +import PantomimeFramework
   89.15 +
   89.16 +extension BasicConnectInfo {
   89.17 +    init?(verifiableAccount: VerifiableAccountProtocol, emailProtocol: EmailProtocol) {
   89.18 +        guard let theAddress = verifiableAccount.address else {
   89.19 +            return nil
   89.20 +        }
   89.21 +
   89.22 +        switch emailProtocol {
   89.23 +        case .imap:
   89.24 +            guard let severAddress = verifiableAccount.serverIMAP else {
   89.25 +                return nil
   89.26 +            }
   89.27 +            self.init(accountEmailAddress: theAddress,
   89.28 +                      loginName: verifiableAccount.loginName,
   89.29 +                      loginPassword: verifiableAccount.password,
   89.30 +                      accessToken: verifiableAccount.accessToken,
   89.31 +                      networkAddress: severAddress,
   89.32 +                      networkPort: verifiableAccount.portIMAP,
   89.33 +                      connectionTransport: verifiableAccount.transportIMAP,
   89.34 +                      authMethod: verifiableAccount.authMethod,
   89.35 +                      emailProtocol: emailProtocol)
   89.36 +        case .smtp:
   89.37 +            guard let severAddress = verifiableAccount.serverSMTP else {
   89.38 +                return nil
   89.39 +            }
   89.40 +            self.init(accountEmailAddress: theAddress,
   89.41 +                      loginName: verifiableAccount.loginName,
   89.42 +                      loginPassword: verifiableAccount.password,
   89.43 +                      accessToken: verifiableAccount.accessToken,
   89.44 +                      networkAddress: severAddress,
   89.45 +                      networkPort: verifiableAccount.portSMTP,
   89.46 +                      connectionTransport: verifiableAccount.transportSMTP,
   89.47 +                      authMethod: verifiableAccount.authMethod,
   89.48 +                      emailProtocol: emailProtocol)
   89.49 +        }
   89.50 +    }
   89.51 +}
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/MessageModel/MessageModel/NetworkService/VerifiableAccount/VerifiableAccountIMAP.swift	Mon May 20 16:30:04 2019 +0200
    90.3 @@ -0,0 +1,64 @@
    90.4 +//
    90.5 +//  VerifiableAccountIMAP.swift
    90.6 +//  pEp
    90.7 +//
    90.8 +//  Created by Dirk Zimmermann on 16.04.19.
    90.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   90.10 +//
   90.11 +
   90.12 +import Foundation
   90.13 +
   90.14 +import PantomimeFramework
   90.15 +import pEpIOSToolbox
   90.16 +
   90.17 +protocol VerifiableAccountIMAPDelegate: class {
   90.18 +    func verified(verifier: VerifiableAccountIMAP,
   90.19 +                  basicConnectInfo: BasicConnectInfo,
   90.20 +                  result: Result<Void, Error>)
   90.21 +}
   90.22 +
   90.23 +/// Helper for `VerifiableAccount` (verifies IMAP servers).
   90.24 +class VerifiableAccountIMAP {
   90.25 +    public weak var verifiableAccountDelegate: VerifiableAccountIMAPDelegate?
   90.26 +
   90.27 +    private var sync: ImapSync?
   90.28 +    private var syncDelegate: VerifiableAccountSyncDelegate?
   90.29 +    private var basicConnectInfo: BasicConnectInfo?
   90.30 +
   90.31 +    /// Tries to verify the given IMAP account.
   90.32 +    public func verify(basicConnectInfo: BasicConnectInfo) {
   90.33 +        self.basicConnectInfo = basicConnectInfo
   90.34 +
   90.35 +        let theSyncDelegate = VerifiableAccountSyncDelegate(errorHandler: self)
   90.36 +        syncDelegate = theSyncDelegate
   90.37 +
   90.38 +        sync = ImapSync(connectInfo: basicConnectInfo)
   90.39 +        sync?.delegate = syncDelegate
   90.40 +        sync?.start()
   90.41 +    }
   90.42 +
   90.43 +    func authenticationCompleted(_ sync: ImapSync, notification: Notification?) {
   90.44 +        self.sync = nil
   90.45 +
   90.46 +        verifiableAccountDelegate?.verified(
   90.47 +            verifier: self,
   90.48 +            basicConnectInfo: BasicConnectInfo.force(basicConnectInfo: basicConnectInfo),
   90.49 +            result: .success(()))
   90.50 +    }
   90.51 +}
   90.52 +
   90.53 +extension VerifiableAccountIMAP: ImapSyncDelegateErrorHandlerProtocol {
   90.54 +    public func handle(error: Error) {
   90.55 +        verifiableAccountDelegate?.verified(
   90.56 +            verifier: self,
   90.57 +            basicConnectInfo: BasicConnectInfo.force(basicConnectInfo: basicConnectInfo),
   90.58 +            result: .failure(error))
   90.59 +    }
   90.60 +}
   90.61 +
   90.62 +class VerifiableAccountSyncDelegate: DefaultImapSyncDelegate {
   90.63 +    override func authenticationCompleted(_ sync: ImapSync, notification: Notification?) {
   90.64 +        (errorHandler as? VerifiableAccountIMAP)?.authenticationCompleted(
   90.65 +            sync, notification: notification)
   90.66 +    }
   90.67 +}
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/MessageModel/MessageModel/NetworkService/VerifiableAccount/VerifiableAccountSMTP.swift	Mon May 20 16:30:04 2019 +0200
    91.3 @@ -0,0 +1,130 @@
    91.4 +//
    91.5 +//  VerifiableAccountSMTP.swift
    91.6 +//  pEp
    91.7 +//
    91.8 +//  Created by Dirk Zimmermann on 17.04.19.
    91.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   91.10 +//
   91.11 +
   91.12 +import Foundation
   91.13 +
   91.14 +import PantomimeFramework
   91.15 +import pEpIOSToolbox
   91.16 +
   91.17 +protocol VerifiableAccountSMTPDelegate: class {
   91.18 +    func verified(verifier: VerifiableAccountSMTP,
   91.19 +                  basicConnectInfo: BasicConnectInfo,
   91.20 +                  result: Result<Void, Error>)
   91.21 +}
   91.22 +
   91.23 +/// Helper for `VerifiableAccount` (verifies SMTP servers).
   91.24 +class VerifiableAccountSMTP {
   91.25 +    public weak var verifiableAccountDelegate: VerifiableAccountSMTPDelegate?
   91.26 +
   91.27 +    private var smtpSend: SmtpSend?
   91.28 +    private var basicConnectInfo: BasicConnectInfo?
   91.29 +
   91.30 +    /// Tries to verify the given IMAP account.
   91.31 +    public func verify(basicConnectInfo: BasicConnectInfo) {
   91.32 +        self.basicConnectInfo = basicConnectInfo
   91.33 +
   91.34 +        smtpSend = SmtpSend(connectInfo: basicConnectInfo)
   91.35 +        smtpSend?.delegate = self
   91.36 +        smtpSend?.start()
   91.37 +    }
   91.38 +}
   91.39 +
   91.40 +extension VerifiableAccountSMTP: SmtpSendDelegate {
   91.41 +    private func forcedConnectInfo() -> BasicConnectInfo {
   91.42 +        return BasicConnectInfo.force(basicConnectInfo: basicConnectInfo)
   91.43 +    }
   91.44 +
   91.45 +    private func notifyUnexpectedCallback(name: String) {
   91.46 +        let error = SmtpSendError.badResponse(name)
   91.47 +        verifiableAccountDelegate?.verified(
   91.48 +            verifier: self,
   91.49 +            basicConnectInfo: forcedConnectInfo(),
   91.50 +            result: .failure(error))
   91.51 +    }
   91.52 +
   91.53 +    private func notify(error: Error) {
   91.54 +        verifiableAccountDelegate?.verified(
   91.55 +            verifier: self,
   91.56 +            basicConnectInfo: forcedConnectInfo(),
   91.57 +            result: .failure(error))
   91.58 +    }
   91.59 +
   91.60 +    public func messageSent(_ smtp: SmtpSend, theNotification: Notification?) {
   91.61 +        notifyUnexpectedCallback(name: #function)
   91.62 +    }
   91.63 +
   91.64 +    public func messageNotSent(_ smtp: SmtpSend, theNotification: Notification?) {
   91.65 +        notifyUnexpectedCallback(name: #function)
   91.66 +    }
   91.67 +
   91.68 +    public func transactionInitiationCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   91.69 +        notifyUnexpectedCallback(name: #function)
   91.70 +    }
   91.71 +
   91.72 +    public func transactionInitiationFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   91.73 +        notifyUnexpectedCallback(name: #function)
   91.74 +    }
   91.75 +
   91.76 +    public func recipientIdentificationCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   91.77 +        notifyUnexpectedCallback(name: #function)
   91.78 +    }
   91.79 +
   91.80 +    public func recipientIdentificationFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   91.81 +        notifyUnexpectedCallback(name: #function)
   91.82 +    }
   91.83 +
   91.84 +    public func transactionResetCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   91.85 +        notifyUnexpectedCallback(name: #function)
   91.86 +    }
   91.87 +
   91.88 +    public func transactionResetFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   91.89 +        notifyUnexpectedCallback(name: #function)
   91.90 +    }
   91.91 +
   91.92 +    public func authenticationCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   91.93 +    }
   91.94 +
   91.95 +    public func authenticationFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   91.96 +        notify(error: SmtpSendError.authenticationFailed(
   91.97 +            #function,
   91.98 +            forcedConnectInfo().accountEmailAddress))
   91.99 +    }
  91.100 +
  91.101 +    public func connectionEstablished(_ smtp: SmtpSend, theNotification: Notification?) {}
  91.102 +
  91.103 +    public func connectionLost(_ smtp: SmtpSend, theNotification: Notification?) {
  91.104 +        notify(error: SmtpSendError.connectionLost(#function))
  91.105 +    }
  91.106 +
  91.107 +    public func connectionTerminated(_ smtp: SmtpSend, theNotification: Notification?) {
  91.108 +        notify(error: SmtpSendError.connectionTerminated(#function))
  91.109 +    }
  91.110 +
  91.111 +    public func connectionTimedOut(_ smtp: SmtpSend, theNotification: Notification?) {
  91.112 +        notify(error: SmtpSendError.connectionTimedOut(#function))
  91.113 +    }
  91.114 +
  91.115 +    public func badResponse(_ smtp: SmtpSend, response: String?) {
  91.116 +        notify(error: SmtpSendError.badResponse(#function))
  91.117 +    }
  91.118 +
  91.119 +    public func requestCancelled(_ smtp: SmtpSend, theNotification: Notification?) {
  91.120 +        notifyUnexpectedCallback(name: #function)
  91.121 +    }
  91.122 +
  91.123 +    public func serviceInitialized(_ smtp: SmtpSend, theNotification: Notification?) {
  91.124 +        verifiableAccountDelegate?.verified(
  91.125 +            verifier: self,
  91.126 +            basicConnectInfo: forcedConnectInfo(),
  91.127 +            result: .success(()))
  91.128 +    }
  91.129 +
  91.130 +    public func serviceReconnected(_ smtp: SmtpSend, theNotification: Notification?) {
  91.131 +        notifyUnexpectedCallback(name: #function)
  91.132 +    }
  91.133 +}
    92.1 --- a/MessageModel/MessageModel/Submodule/CoreData/CdMessage+Util.swift	Fri May 03 12:19:46 2019 +0200
    92.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/CdMessage+Util.swift	Mon May 20 16:30:04 2019 +0200
    92.3 @@ -34,13 +34,13 @@
    92.4          if !theRefs.isEmpty {
    92.5              for ref in theRefs {
    92.6                  if let refID = ref.reference {
    92.7 -                    Log.shared.info(component: #function,
    92.8 -                                    content: "messageID \(theUuid) -> ref \(refID)")
    92.9 +                    let info = "messageID \(theUuid) -> ref \(refID)"
   92.10 +                    Log.shared.info("%@", info)
   92.11                  }
   92.12              }
   92.13          } else {
   92.14 -            Log.shared.info(component: #function,
   92.15 -                            content: "messageID \(theUuid) -> no refs")
   92.16 +            let info = "messageID \(theUuid) -> no refs"
   92.17 +            Log.shared.info("%@", info)
   92.18          }
   92.19      }
   92.20  
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdAccount+Trusted.swift	Mon May 20 16:30:04 2019 +0200
    93.3 @@ -0,0 +1,18 @@
    93.4 +//
    93.5 +//  CdAccount+Trusted.swift
    93.6 +//  MessageModel
    93.7 +//
    93.8 +//  Created by Alejandro Gelos on 15/05/2019.
    93.9 +//  Copyright © 2019 pEp Security S.A. All rights reserved.
   93.10 +//
   93.11 +
   93.12 +import Foundation
   93.13 +
   93.14 +extension CdAccount {
   93.15 +    var isTrusted: Bool {
   93.16 +        guard let imapServer = imapCdServer else {
   93.17 +            return false
   93.18 +        }
   93.19 +        return imapServer.manuallyTrusted || imapServer.automaticallyTrusted
   93.20 +    }
   93.21 +}
    94.1 --- a/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdAccount.swift	Fri May 03 12:19:46 2019 +0200
    94.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdAccount.swift	Mon May 20 16:30:04 2019 +0200
    94.3 @@ -30,9 +30,8 @@
    94.4                  CdIdentity.AttributeName.address + " like[c] %@" , account.user.address)
    94.5          let cdAcc = CdAccount.first(predicate: p, in: moc)
    94.6          if cdAcc == nil {
    94.7 -            Log.shared.info(
    94.8 -                component: #function,
    94.9 -                content: "Did not find account by address: \(account.user.address)")
   94.10 +            let error = "Did not find account by address: \(account.user.address)"
   94.11 +            Log.shared.info("%@", error)
   94.12          }
   94.13          return cdAcc
   94.14      }
   94.15 @@ -44,7 +43,8 @@
   94.16      ///             nil otherwize
   94.17      public func removeServer(of type: Server.ServerType) {
   94.18          guard let existing = server(type: type) else {
   94.19 -            Log.shared.info(component: #function, content: "An attempt to remove an non-existing server with type \(type.asString()) has been made for account \(String(describing: self.identity?.address))")
   94.20 +            let info = "An attempt to remove an non-existing server with type \(type.asString()) has been made for account \(String(describing: self.identity?.address))"
   94.21 +            Log.shared.info("%@", info)
   94.22              return
   94.23          }
   94.24  
   94.25 @@ -56,8 +56,7 @@
   94.26      /// - Parameter account: account to take identity from
   94.27      public func updateIdentity(with account: Account) {
   94.28          guard let identity = self.identity else {
   94.29 -            Log.shared.errorAndCrash(component: #function,
   94.30 -                                     errorString: "I (CdAccount) am missing the mandatory field \"identity\"")
   94.31 +            Log.shared.errorAndCrash("I (CdAccount) am missing the mandatory field \"identity\"")
   94.32              return
   94.33          }
   94.34          identity.address = account.user.address
   94.35 @@ -77,7 +76,7 @@
   94.36              cdServer.update(with: server)
   94.37          } else {
   94.38              guard let cdServer = CdServer.save(server) as? CdServer else {
   94.39 -                Log.shared.errorAndCrash(component: #function, errorString: "Something is fishy.")
   94.40 +                Log.shared.errorAndCrash("Something is fishy.")
   94.41                  return
   94.42              }
   94.43              addToServers(cdServer)
   94.44 @@ -135,8 +134,8 @@
   94.45          }
   94.46  
   94.47          if serversWithType.count > 1 {
   94.48 -            Log.shared.errorAndCrash(component: #function,
   94.49 -                                     errorString: "Invalid state. CdAccount \(String(describing: identity?.address)) has more than one server of type \(type.asString()) assigned. Assigned servers: \(serversWithType)")
   94.50 +            let error = "Invalid state. CdAccount \(String(describing: identity?.address)) has more than one server of type \(type.asString()) assigned. Assigned servers: \(serversWithType)"
   94.51 +            Log.shared.errorAndCrash("%@", error)
   94.52          }
   94.53  
   94.54          return serversWithType.first
    95.1 --- a/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdFolder.swift	Fri May 03 12:19:46 2019 +0200
    95.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdFolder.swift	Mon May 20 16:30:04 2019 +0200
    95.3 @@ -14,7 +14,7 @@
    95.4      open var folderType: FolderType {
    95.5          get {
    95.6              guard let type = FolderType(rawValue: self.folderTypeRawValue) else {
    95.7 -                Log.shared.errorAndCrash(component: #function, errorString: "No type?!")
    95.8 +                Log.shared.errorAndCrash("No type?!")
    95.9                  return FolderType.normal
   95.10              }
   95.11              return type
   95.12 @@ -39,11 +39,11 @@
   95.13          let account = folder.account
   95.14  
   95.15          guard let cdAccount = CdAccount.search(account: account) else {
   95.16 -            Log.shared.errorAndCrash(component: #function, errorString: "Non existing account?")
   95.17 +            Log.shared.errorAndCrash("Non existing account?")
   95.18              return nil
   95.19          }
   95.20          guard let cdFolder = search(folder: folder) ?? CdFolder.create(folder: folder) else {
   95.21 -            Log.shared.errorAndCrash(component: #function, errorString: "Error creating folder")
   95.22 +            Log.shared.errorAndCrash("Error creating folder")
   95.23              return nil
   95.24          }
   95.25          cdFolder.updateValues(folder: folder, cdAccount: cdAccount)
   95.26 @@ -54,13 +54,7 @@
   95.27      public static func search(folder: Folder) -> CdFolder? {
   95.28          let account = folder.account
   95.29          guard let cdAccount = CdAccount.search(account: account) else {
   95.30 -            Log.shared.warn(component: #function,
   95.31 -                            content:
   95.32 -                """
   95.33 -                No account for the folders has been found. That can happen if the user has just
   95.34 -deleted it while we are accessing this method concurrently.
   95.35 -"""
   95.36 -            )
   95.37 +            Log.shared.warn("No account for the folders has been found. That can happen if the user has just deleted it while we are accessing this method concurrently.")
   95.38              return nil
   95.39          }
   95.40          //For IMAP the combination (name, account) assures uniqueness due to IMAPs folder
   95.41 @@ -81,8 +75,7 @@
   95.42              return nil
   95.43          }
   95.44          if results.count > 1 {
   95.45 -            Log.shared.errorAndCrash(component: #function,
   95.46 -                                     errorString: "We found more than one folder where it hould be unique.")
   95.47 +            Log.shared.errorAndCrash("We found more than one folder where it hould be unique.")
   95.48          }
   95.49          return results.first as? CdFolder
   95.50      }
   95.51 @@ -90,8 +83,8 @@
   95.52      @discardableResult static public func create(folder: Folder) -> CdFolder? {
   95.53          let account = folder.account
   95.54          guard let cdAccount = CdAccount.search(account: account) else {
   95.55 -            Log.shared.errorAndCrash(component: #function,
   95.56 -                                     errorString: "Account of folder does not exist yet. Folder: \(folder)")
   95.57 +            let error = "Account of folder does not exist yet. Folder: \(folder)"
   95.58 +            Log.shared.errorAndCrash("%@", error)
   95.59              return nil
   95.60          }
   95.61          let cdFolder = CdFolder.create()
    96.1 --- a/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdMessage.swift	Fri May 03 12:19:46 2019 +0200
    96.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdMessage.swift	Mon May 20 16:30:04 2019 +0200
    96.3 @@ -72,11 +72,8 @@
    96.4              //filter fake msgs
    96.5              found = found.filter { $0.uid != -1 }
    96.6              if found.count > 1 {
    96.7 -                Log.shared.errorAndCrash(component: #function,
    96.8 -                                         errorString:
    96.9 -                    """
   96.10 -                    Multiple messages with UUID \(uuid) in folder \(folderName). Messages: \(found)
   96.11 -                    """)
   96.12 +                let error = "Multiple messages with UUID \(uuid) in folder \(folderName). Messages: \(found)"
   96.13 +                Log.shared.errorAndCrash("%@", error)
   96.14              }
   96.15          }
   96.16          return found.first
   96.17 @@ -92,9 +89,8 @@
   96.18              return nil
   96.19          }
   96.20          if messages.count > 1 {
   96.21 -            Log.shared.errorAndCrash(component: #function,
   96.22 -                                     errorString:
   96.23 -                "Multiple messages with UID \(uid) in folder \(folderName)")
   96.24 +            let error = "Multiple messages with UID \(uid) in folder \(folderName)"
   96.25 +            Log.shared.errorAndCrash("%@", error)
   96.26          }
   96.27          return messages.first
   96.28      }
   96.29 @@ -109,9 +105,8 @@
   96.30              return nil
   96.31          }
   96.32          if messages.count > 1 {
   96.33 -            Log.shared.errorAndCrash(component: #function,
   96.34 -                                     errorString:
   96.35 -                "Multiple messages with UID \(uid) in folder \(folderName)")
   96.36 +            let error = "Multiple messages with UID \(uid) in folder \(folderName)"
   96.37 +            Log.shared.errorAndCrash("%@", error)
   96.38          }
   96.39          return messages.first
   96.40      }
   96.41 @@ -132,7 +127,7 @@
   96.42      /// - Returns: existing message if found, nil otherwize
   96.43      public static func search(message: Message) -> CdMessage? {
   96.44          guard  let cdAccount = CdAccount.search(account: message.parent.account) else {
   96.45 -            Log.shared.errorAndCrash(component: #function, errorString: "Account not found?")
   96.46 +            Log.shared.errorAndCrash("Account not found?")
   96.47              return nil
   96.48          }
   96.49          return search(uid: Int32(message.uid),
   96.50 @@ -167,12 +162,12 @@
   96.51              // one folder, so we take the first.
   96.52              let msgs = by(uuid: uuid, account: account)
   96.53              if msgs.count > 1 {
   96.54 -                Log.shared.errorAndCrash(component: #function, errorString:
   96.55 -                    """
   96.56 -                    We found multiple CdMessages with UUID \(uuid).
   96.57 -                    As this is all we have, we take the first.
   96.58 -                    Messages: \(msgs)
   96.59 -                    """)
   96.60 +                let error = """
   96.61 +                We found multiple CdMessages with UUID \(uuid).
   96.62 +                As this is all we have, we take the first.
   96.63 +                Messages: \(msgs)
   96.64 +                """
   96.65 +                Log.shared.errorAndCrash("%@", error)
   96.66              }
   96.67              return msgs.first
   96.68          }
   96.69 @@ -314,7 +309,7 @@
   96.70              // To work around we delete the attachment imstead.
   96.71              for cdAttachment in existingCdAttachments {
   96.72                  guard let safeCdAttachment = cdAttachment as? CdAttachment else {
   96.73 -                    Log.shared.errorAndCrash(component: #function, errorString: "Cast failed")
   96.74 +                    Log.shared.errorAndCrash("Cast failed")
   96.75                      continue
   96.76                  }
   96.77                  safeCdAttachment.delete()
   96.78 @@ -331,7 +326,7 @@
   96.79          if let existingCdHeaderFiles = self.optionalFields {
   96.80              for cdheader in existingCdHeaderFiles {
   96.81                  guard let deleteOptionalField = cdheader as? CdHeaderField else {
   96.82 -                    Log.shared.errorAndCrash(component: #function, errorString: "Cast failed")
   96.83 +                    Log.shared.errorAndCrash("Cast failed")
   96.84                      continue
   96.85                  }
   96.86                  deleteOptionalField.delete()
   96.87 @@ -413,7 +408,7 @@
   96.88      @available(*, deprecated, message: "Use MessageModelObjectUtils().getMessage(fromCdMessage:)")
   96.89      open func message() -> Message? {
   96.90          guard let moc = self.managedObjectContext else {
   96.91 -            Log.shared.errorAndCrash(component: #function, errorString: "MO without moc")
   96.92 +            Log.shared.errorAndCrash("MO without moc")
   96.93              return nil
   96.94          }
   96.95          if moc === Record.Context.main {
   96.96 @@ -440,8 +435,7 @@
   96.97      private func messageInternal() -> Message? {
   96.98          guard let theUuid = uuid,
   96.99              let theParent = parent else {
  96.100 -                Log.shared.errorAndCrash(component: #function,
  96.101 -                                         errorString: "Mandatory field not set.")
  96.102 +                Log.shared.errorAndCrash( "Mandatory field not set.")
  96.103                  return nil
  96.104          }
  96.105  
  96.106 @@ -471,7 +465,7 @@
  96.107          message.to = identities(orderedSet: to)
  96.108          message.imapFlags = imap?.imapFlags()
  96.109          if message.imapFlags == nil {
  96.110 -            Log.shared.warn(component: #function, content: "message.imapFlags == nil")
  96.111 +            Log.shared.warn("message.imapFlags == nil")
  96.112          }
  96.113          for item in references?.array as? [CdMessageReference] ?? [] {
  96.114              if let ref = item.reference {
    97.1 --- a/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdServer.swift	Fri May 03 12:19:46 2019 +0200
    97.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdServer.swift	Mon May 20 16:30:04 2019 +0200
    97.3 @@ -21,7 +21,8 @@
    97.4  
    97.5      static private func insertServer(server: Server) -> CdServer {
    97.6          let cdServer = CdServer.create()
    97.7 -        cdServer.trusted = server.trusted
    97.8 +        cdServer.automaticallyTrusted = server.automaticallyTrusted
    97.9 +        cdServer.manuallyTrusted = server.manuallyTrusted
   97.10          cdServer.address = server.address
   97.11          cdServer.authMethod = server.authMethod
   97.12          cdServer.serverType = server.serverType
   97.13 @@ -31,7 +32,7 @@
   97.14          }
   97.15          guard let cdCredentials = CdServerCredentials.save(server.credentials) as? CdServerCredentials
   97.16              else {
   97.17 -            Log.shared.errorAndCrash(component: #function, errorString: "Should not happen :-/")
   97.18 +            Log.shared.errorAndCrash("Should not happen :-/")
   97.19              return cdServer
   97.20          }
   97.21          cdServer.credentials = cdCredentials
   97.22 @@ -40,7 +41,8 @@
   97.23      }
   97.24  
   97.25      public func update(with server: Server) {
   97.26 -        self.trusted = server.trusted
   97.27 +        self.automaticallyTrusted = server.automaticallyTrusted
   97.28 +        self.manuallyTrusted = server.manuallyTrusted
   97.29          self.address = server.address
   97.30          self.serverType = server.serverType
   97.31          self.port = NSNumber(value: server.port)
   97.32 @@ -54,8 +56,7 @@
   97.33                  let newCdCredentials = CdServerCredentials.save(server.credentials)
   97.34                      as? CdServerCredentials
   97.35                  else {
   97.36 -                    Log.shared.errorAndCrash(component: #function,
   97.37 -                                             errorString: "We have a problem here.")
   97.38 +                    Log.shared.errorAndCrash("We have a problem here.")
   97.39                      return
   97.40              }
   97.41              self.credentials = newCdCredentials
    98.1 --- a/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdServerCredentials.swift	Fri May 03 12:19:46 2019 +0200
    98.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/NSManagedObjectExtensions/CdServerCredentials.swift	Mon May 20 16:30:04 2019 +0200
    98.3 @@ -49,9 +49,8 @@
    98.4      public var account: CdAccount? {
    98.5          get {
    98.6              guard let serv = servers?.anyObject() as? CdServer else {
    98.7 -                Log.shared.errorAndCrash(component: #function,
    98.8 -                                         errorString:
    98.9 -                    "Mandatory field \"servers\" not set in CdServerCredentials: \(self)")
   98.10 +                let error = "Mandatory field \"servers\" not set in CdServerCredentials: \(self)"
   98.11 +                Log.shared.errorAndCrash("%@", error)
   98.12                  return nil
   98.13              }
   98.14              return serv.account
   98.15 @@ -87,7 +86,7 @@
   98.16          } else {
   98.17              // It is not a new credential ...
   98.18              guard let key = credentials.key else {
   98.19 -                Log.shared.errorAndCrash(component: #function, errorString: "No key.")
   98.20 +                Log.shared.errorAndCrash("No key.")
   98.21                  return
   98.22              }
   98.23              // For OAuth2 accounts, the key is generated beforehand to make the
    99.1 --- a/MessageModel/MessageModel/Submodule/CoreData/Stack.swift	Fri May 03 12:19:46 2019 +0200
    99.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/Stack.swift	Mon May 20 16:30:04 2019 +0200
    99.3 @@ -172,8 +172,7 @@
    99.4              do {
    99.5                  fetchedObjects = try context.fetch(request)
    99.6              } catch {
    99.7 -                Log.shared.errorAndCrash(component: "#file - \(#function)[\(#line)]",
    99.8 -                    errorString: "\(error)")
    99.9 +                Log.shared.errorAndCrash("%@", error.localizedDescription)
   99.10              }
   99.11          }
   99.12          return fetchedObjects
   99.13 @@ -200,8 +199,7 @@
   99.14                      // turn managed object into fault
   99.15                      context.refresh(managedObject, mergeChanges: mergeChanges)
   99.16                  } catch {
   99.17 -                    Log.shared.errorAndCrash(component: "#file - \(#function)[\(#line)]",
   99.18 -                        errorString: "\(error)")
   99.19 +                    Log.shared.errorAndCrash("%@", error.localizedDescription)
   99.20                  }
   99.21              }
   99.22          }
   100.1 --- a/MessageModel/MessageModel/Submodule/CoreData/gen/CoreDataEntityAttributeNames.swift	Fri May 03 12:19:46 2019 +0200
   100.2 +++ b/MessageModel/MessageModel/Submodule/CoreData/gen/CoreDataEntityAttributeNames.swift	Mon May 20 16:30:04 2019 +0200
   100.3 @@ -213,11 +213,12 @@
   100.4      public struct AttributeName {
   100.5          static public let address = "address"
   100.6          static public let authMethod = "authMethod"
   100.7 +        static public let automaticallyTrusted = "automaticallyTrusted"
   100.8          static public let imapFolderSeparator = "imapFolderSeparator"
   100.9 +        static public let manuallyTrusted = "manuallyTrusted"
  100.10          static public let port = "port"
  100.11          static public let serverTypeRawValue = "serverTypeRawValue"
  100.12          static public let transportRawValue = "transportRawValue"
  100.13 -        static public let trusted = "trusted"
  100.14      }
  100.15  
  100.16      /// All relationship names as constant String
   101.1 --- a/MessageModel/MessageModel/Util/KeyChain.swift	Fri May 03 12:19:46 2019 +0200
   101.2 +++ b/MessageModel/MessageModel/Util/KeyChain.swift	Mon May 20 16:30:04 2019 +0200
   101.3 @@ -15,7 +15,6 @@
   101.4   */
   101.5  public class KeyChain {
   101.6      public typealias Success = Bool
   101.7 -    static private let comp = "KeyChain"
   101.8      static private let defaultServerType = "Server"
   101.9  
  101.10      // MARK: - API
  101.11 @@ -39,12 +38,12 @@
  101.12          }
  101.13  
  101.14          if status != noErr {
  101.15 -            Log.shared.warn(component: comp,
  101.16 -                            content: "Could not get password for \(key), status \(status)")
  101.17 +            let warn = "Could not get password for \(key), status \(status)"
  101.18 +            Log.shared.warn("%@", warn)
  101.19          }
  101.20          guard let r = result as? Data else {
  101.21 -            Log.shared.warn(component: comp,
  101.22 -                            content: "No password found for \(key)")
  101.23 +            let warn = "No password found for \(key)"
  101.24 +            Log.shared.warn("%@", warn)
  101.25              return nil
  101.26          }
  101.27          let str = String(data: r, encoding: String.Encoding.utf8)
  101.28 @@ -100,9 +99,8 @@
  101.29                                                 password: String?) -> Success {
  101.30          guard let pass = password else {
  101.31              // No password, so nothing need to be done. Give a warning though.
  101.32 -            Log.shared.warn(
  101.33 -                component: comp,
  101.34 -                content: "Cannot add nil password. Key: \(key), serverType: \(serverType)")
  101.35 +            let warn = "Cannot add nil password. Key: \(key), serverType: \(serverType)"
  101.36 +            Log.shared.warn("%@", warn)
  101.37              return false
  101.38          }
  101.39          let query = [
  101.40 @@ -116,8 +114,8 @@
  101.41  
  101.42          let status = SecItemAdd(query as CFDictionary, nil)
  101.43          if status != noErr {
  101.44 -            Log.shared.warn(component: comp,
  101.45 -                            content: "Could not save password for \(key), status \(status)")
  101.46 +            let warn = "Could not save password for \(key), status \(status)"
  101.47 +            Log.shared.warn("%@", warn)
  101.48              return false
  101.49          }
  101.50          return true
  101.51 @@ -126,7 +124,8 @@
  101.52      @discardableResult static private func update(key: String, newPassword: String?) -> Success {
  101.53          guard let password = newPassword,
  101.54              let passwordData = password.data(using: String.Encoding.utf8) else {
  101.55 -                Log.shared.warn(component: comp, content: "Cannot update nil password. Key: \(key)")
  101.56 +                let warn = "Cannot update nil password. Key: \(key)"
  101.57 +                Log.shared.warn("%@", warn)
  101.58                  return false
  101.59          }
  101.60  
  101.61 @@ -136,8 +135,8 @@
  101.62                             kSecAttrAccount as String:key]
  101.63          let status = SecItemUpdate(searchQuery as CFDictionary, updateQuery as CFDictionary)
  101.64          guard status == noErr else {
  101.65 -            Log.shared.warn(component: comp,
  101.66 -                            content: "Could not update password for \(key), status \(status)")
  101.67 +            let warn = "Could not update password for \(key), status \(status)"
  101.68 +            Log.shared.warn("%@", warn)
  101.69              return false
  101.70          }
  101.71          return true
  101.72 @@ -148,8 +147,8 @@
  101.73                             kSecAttrAccount as String:key]
  101.74          let status = SecItemDelete(deleteQuery as CFDictionary)
  101.75          if status != noErr {
  101.76 -            Log.shared.warn(component: comp,
  101.77 -                            content: "Could not delete password for \(key), status \(status)")
  101.78 +            let warn = "Could not delete password for \(key), status \(status)"
  101.79 +            Log.shared.warn("%@", warn)
  101.80              return false
  101.81          } else {
  101.82              return true
   102.1 --- a/MessageModel/MessageModel/Util/Log.swift	Fri May 03 12:19:46 2019 +0200
   102.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.3 @@ -1,11 +0,0 @@
   102.4 -//
   102.5 -//  Log.swift
   102.6 -//  MessageModel
   102.7 -//
   102.8 -//  Created by Dirk Zimmermann on 14/12/16.
   102.9 -//  Copyright © 2016 pEp Security S.A. All rights reserved.
  102.10 -//
  102.11 -
  102.12 -class Log {
  102.13 -    static let shared: MessageModelLogging = MessageModelConfig.logger
  102.14 -}
   103.1 --- a/MessageModel/MessageModel/Util/MessageModelConfig.swift	Fri May 03 12:19:46 2019 +0200
   103.2 +++ b/MessageModel/MessageModel/Util/MessageModelConfig.swift	Mon May 20 16:30:04 2019 +0200
   103.3 @@ -17,16 +17,12 @@
   103.4       */
   103.5      public static var cache = NSCache<NSString, AnyObject>()
   103.6  
   103.7 -    public static var logger: MessageModelLogging = PrintLogger()
   103.8 -
   103.9 -
  103.10      // MARK: - Delegates
  103.11  
  103.12      public static weak var messageFolderDelegate: MessageFolderDelegate?
  103.13  
  103.14      public static func reset() {
  103.15          cache = NSCache<NSString, AnyObject>()
  103.16 -        logger = PrintLogger()
  103.17          messageFolderDelegate = nil
  103.18      }
  103.19  }
   104.1 --- a/MessageModel/MessageModel/Util/MessageModelObjectUtils.swift	Fri May 03 12:19:46 2019 +0200
   104.2 +++ b/MessageModel/MessageModel/Util/MessageModelObjectUtils.swift	Mon May 20 16:30:04 2019 +0200
   104.3 @@ -72,8 +72,7 @@
   104.4      private func getManagedObjectContext(fromCdMessage cdMessage: CdMessage)
   104.5                                                              -> NSManagedObjectContext? {
   104.6          guard let managedObjectContext = cdMessage.managedObjectContext else {
   104.7 -            Log.shared.errorAndCrash(component: #function,
   104.8 -            errorString: "MO without managedObjectContext")
   104.9 +            Log.shared.errorAndCrash("MO without managedObjectContext")
  104.10              return nil
  104.11          }
  104.12          return managedObjectContext
  104.13 @@ -95,8 +94,7 @@
  104.14      
  104.15      private func getMessageLogic(fromCdMessage cdMessage: CdMessage) -> Message? {
  104.16          guard let uuid = cdMessage.uuid, let parent = cdMessage.parent else {
  104.17 -            Log.shared.errorAndCrash(component: #function,
  104.18 -                                     errorString: "Mandatory field not set.")
  104.19 +            Log.shared.errorAndCrash("Mandatory field not set.")
  104.20              return nil
  104.21          }
  104.22          
  104.23 @@ -122,7 +120,7 @@
  104.24          if let id = cdMessage.from { message.from = Identity.from(cdIdentity: id) }
  104.25          
  104.26          if let _ = message.imapFlags {
  104.27 -            Log.shared.warn(component: #function, content: "message.imapFlags == nil")
  104.28 +            Log.shared.warn("message.imapFlags == nil")
  104.29          }
  104.30          
  104.31          return message
   105.1 --- a/MessageModel/MessageModel/Util/PersistentSetup.swift	Fri May 03 12:19:46 2019 +0200
   105.2 +++ b/MessageModel/MessageModel/Util/PersistentSetup.swift	Mon May 20 16:30:04 2019 +0200
   105.3 @@ -74,7 +74,7 @@
   105.4                  }
   105.5              }
   105.6          } catch {
   105.7 -            Logger.backendLogger.log(error: error)
   105.8 +            Log.shared.log(error: error)
   105.9          }
  105.10      }
  105.11  
  105.12 @@ -85,7 +85,7 @@
  105.13                  managedObjectModel: objectModel, storeType: storeType,
  105.14                  storeURL: defaultURL)
  105.15          } catch {
  105.16 -            Logger.backendLogger.log(error: error)
  105.17 +            Log.shared.log(error: error)
  105.18          }
  105.19      }
  105.20  
  105.21 @@ -94,7 +94,7 @@
  105.22              try Record.destroyCoreDataStack(managedObjectModel: objectModel,
  105.23                                              storeType: storeType, storeURL: defaultURL)
  105.24          } catch {
  105.25 -            Logger.backendLogger.log(error: error)
  105.26 +            Log.shared.log(error: error)
  105.27          }
  105.28      }
  105.29  }
   106.1 --- a/MessageModel/MessageModel/Util/PredicateFacories/CdMessage+PredicateFactory.swift	Fri May 03 12:19:46 2019 +0200
   106.2 +++ b/MessageModel/MessageModel/Util/PredicateFacories/CdMessage+PredicateFactory.swift	Mon May 20 16:30:04 2019 +0200
   106.3 @@ -83,19 +83,12 @@
   106.4          }
   106.5  
   106.6          static public func hasViewableAttachments(value: Bool) -> NSPredicate {
   106.7 -            //FIXME: See IOS-1511
   106.8 -            let contentTypeApplicationPGPKeys = "application/pgp-keys"
   106.9 -            //FIXME: See IOS-1511
  106.10 -            let unviewableMimeTypes = Set([
  106.11 -                contentTypeApplicationPGPKeys,
  106.12 -                "application/pgp-signature"]
  106.13 -            )
  106.14              let type = (value) ? ">" : "="
  106.15              let viewableOnly = NSPredicate(
  106.16                  format: "(SUBQUERY(%K, $a, (not ($a.%K in %@)))).@count \(type) 0",
  106.17                  CdMessage.RelationshipName.attachments,
  106.18                  CdAttachment.AttributeName.mimeType,
  106.19 -                unviewableMimeTypes)
  106.20 +                MimeTypeUtils.unviewableMimeTypes)
  106.21              return viewableOnly
  106.22          }
  106.23  
   107.1 --- a/MessageModel/MessageModel/Util/PredicateFacories/CdServer+PredicateFactory.swift	Fri May 03 12:19:46 2019 +0200
   107.2 +++ b/MessageModel/MessageModel/Util/PredicateFacories/CdServer+PredicateFactory.swift	Mon May 20 16:30:04 2019 +0200
   107.3 @@ -14,7 +14,7 @@
   107.4  
   107.5          static public func isAllowedToManuallyTrust() -> NSPredicate {
   107.6              let pImap = isImap()
   107.7 -            let pNotInLocalNetworkWhenCreated = notTrusted()
   107.8 +            let pNotInLocalNetworkWhenCreated = notAutomaticallyTrusted()
   107.9              return
  107.10                  NSCompoundPredicate(andPredicateWithSubpredicates: [pImap,
  107.11                                                                      pNotInLocalNetworkWhenCreated])
  107.12 @@ -26,8 +26,8 @@
  107.13                                           Server.ServerType.imap.rawValue)
  107.14          }
  107.15  
  107.16 -        static public func notTrusted() -> NSPredicate {
  107.17 -            return NSPredicate(format: "%K = false", CdServer.AttributeName.trusted)
  107.18 +        static public func notAutomaticallyTrusted() -> NSPredicate {
  107.19 +            return NSPredicate(format: "%K = false", CdServer.AttributeName.automaticallyTrusted)
  107.20          }
  107.21      }
  107.22  }
   108.1 --- a/MessageModel/MessageModelTests/Helper/TestUtil.swift	Fri May 03 12:19:46 2019 +0200
   108.2 +++ b/MessageModel/MessageModelTests/Helper/TestUtil.swift	Mon May 20 16:30:04 2019 +0200
   108.3 @@ -160,13 +160,18 @@
   108.4                               serverTransport: Server.Transport = .startTls,
   108.5                               password: String = "fakePassword",
   108.6                               loginName: String = "fakeLoginName",
   108.7 +                             automaticallyTrusted: Bool = false,
   108.8 +                             manuallyTrusted: Bool = false,
   108.9 +                             serverType: Server.ServerType,
  108.10                               moc: NSManagedObjectContext) -> CdServer {
  108.11          //SMTP
  108.12          let createe = CdServer(context: moc)
  108.13 -        createe.serverType = .smtp
  108.14 +        createe.serverType = serverType
  108.15          createe.port = NSNumber(value: serverPort)
  108.16          createe.address = serverAddress
  108.17          createe.transport = serverTransport
  108.18 +        createe.automaticallyTrusted = automaticallyTrusted
  108.19 +        createe.manuallyTrusted = manuallyTrusted
  108.20  
  108.21          let keychainKeySmtp = MessageID.generate()
  108.22          CdServerCredentials.add(password: password, forKey: keychainKeySmtp)
  108.23 @@ -221,6 +226,7 @@
  108.24                                  serverTransport: smtpServerTransport,
  108.25                                  password: smtpPassword,
  108.26                                  loginName: smtpLoginName ?? idAddress,
  108.27 +                                serverType: .smtp,
  108.28                                  moc: moc)
  108.29          acc.addToServers(smtp)
  108.30  
  108.31 @@ -230,6 +236,7 @@
  108.32                                  serverTransport: imapServerTransport,
  108.33                                  password: imapPassword,
  108.34                                  loginName: imapLoginName ?? idAddress,
  108.35 +                                serverType: .imap,
  108.36                                  moc: moc)
  108.37          acc.addToServers(imap)
  108.38  
   109.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.2 +++ b/MessageModel/MessageModelTests/Interface/MessageModelObjects/Account+FetchingTest.swift	Mon May 20 16:30:04 2019 +0200
   109.3 @@ -0,0 +1,80 @@
   109.4 +//
   109.5 +//  Account+FetchingTest.swift
   109.6 +//  MessageModelTests
   109.7 +//
   109.8 +//  Created by Alejandro Gelos on 25/04/2019.
   109.9 +//  Copyright © 2019 pEp Security S.A. All rights reserved.
  109.10 +//
  109.11 +
  109.12 +import XCTest
  109.13 +import CoreData
  109.14 +@testable import MessageModel
  109.15 +
  109.16 +class Acount_FetchingTest: XCTestCase {
  109.17 +    var persistentSetup: PersistentSetup!
  109.18 +    var mainContext: NSManagedObjectContext!
  109.19 +    var cdAccount1: CdAccount!
  109.20 +    var cdAccount2: CdAccount!
  109.21 +    var cdAccount3: CdAccount!
  109.22 +
  109.23 +    override func setUp() {
  109.24 +        super.setUp()
  109.25 +
  109.26 +        persistentSetup = PersistentSetup(storeType: NSInMemoryStoreType)
  109.27 +        self.mainContext = Stack.shared.mainContext
  109.28 +
  109.29 +        //Account 1
  109.30 +        cdAccount1 = TestUtil.createFakeAccount(moc: mainContext)
  109.31 +
  109.32 +        //Account 2
  109.33 +        cdAccount2 = TestUtil.createFakeAccount(idAddress: "account2@test.com",
  109.34 +                                              idUserName: "test2",
  109.35 +                                              moc: mainContext)
  109.36 +
  109.37 +        cdAccount3 = TestUtil.createFakeAccount(idAddress: "account3@test.com",
  109.38 +                                              idUserName: "test3",
  109.39 +                                              moc: mainContext)
  109.40 +        let account3 = cdAccount3.account()
  109.41 +        account3.imapServer!.automaticallyTrusted = true
  109.42 +        account3.save()
  109.43 +
  109.44 +        mainContext.saveAndLogErrors()
  109.45 +    }
  109.46 +
  109.47 +    override func tearDown() {
  109.48 +        persistentSetup = nil
  109.49 +        cdAccount1 = nil
  109.50 +        cdAccount2 = nil
  109.51 +        super.tearDown()
  109.52 +    }
  109.53 +
  109.54 +    func testGetAllAccountsAllowedToManuallyTrust() {
  109.55 +        // Given
  109.56 +        let expectedAllowedAccounts = Set([cdAccount1.account(), cdAccount2.account()])
  109.57 +        let expectedAllowedAccountCount = 2
  109.58 +
  109.59 +        // When
  109.60 +        let allowedAccounts = Set(Account.Fetch.allAccountsAllowedToManuallyTrust())
  109.61 +
  109.62 +        // Then
  109.63 +        XCTAssertEqual(allowedAccounts.count, expectedAllowedAccountCount)
  109.64 +        XCTAssertEqual(allowedAccounts, expectedAllowedAccounts)
  109.65 +    }
  109.66 +
  109.67 +    func testGetAccountByAddres() {
  109.68 +        // Given
  109.69 +        let address1 = cdAccount1.account().user.address
  109.70 +        let address2 = cdAccount2.account().user.address
  109.71 +        let address3 = cdAccount3.account().user.address
  109.72 +
  109.73 +        // When
  109.74 +        let account1 = Account.Fetch.accountAllowedToManuallyTrust(fromAddress: address1)
  109.75 +        let account2 = Account.Fetch.accountAllowedToManuallyTrust(fromAddress: address2)
  109.76 +        let account3 = Account.Fetch.accountAllowedToManuallyTrust(fromAddress: address3)
  109.77 +
  109.78 +        // Then
  109.79 +        XCTAssertEqual(cdAccount1.account(), account1)
  109.80 +        XCTAssertEqual(cdAccount2.account(), account2)
  109.81 +        XCTAssertNotEqual(cdAccount3.account(), account3)
  109.82 +    }
  109.83 +}
   110.1 --- a/MessageModel/MessageModelTests/MessageModelTests.swift	Fri May 03 12:19:46 2019 +0200
   110.2 +++ b/MessageModel/MessageModelTests/MessageModelTests.swift	Mon May 20 16:30:04 2019 +0200
   110.3 @@ -121,14 +121,14 @@
   110.4      func testSaveTrustedServer() {
   110.5          let dummyCredentials = ServerCredentials.create(loginName: "dummy")
   110.6          let s1 = Server.create(serverType: .imap, port: 4096, address: "what", transport: .tls,
   110.7 -                               trusted: true, credentials: dummyCredentials)
   110.8 +                               automaticallyTrusted: true, credentials: dummyCredentials)
   110.9          s1.save()
  110.10          
  110.11          guard let cdServer = CdServer.first() else {
  110.12              XCTFail()
  110.13              return
  110.14          }
  110.15 -        XCTAssertTrue(cdServer.trusted)
  110.16 +        XCTAssertTrue(cdServer.automaticallyTrusted)
  110.17      }
  110.18  
  110.19      func testAccountSave() {
   111.1 --- a/MessageModel/MessageModelTests/Modules/Log/LogTest.swift	Fri May 03 12:19:46 2019 +0200
   111.2 +++ b/MessageModel/MessageModelTests/Modules/Log/LogTest.swift	Mon May 20 16:30:04 2019 +0200
   111.3 @@ -13,6 +13,6 @@
   111.4  class LogTest: XCTestCase {
   111.5  
   111.6      func testSharedNotNil() {
   111.7 -        XCTAssertNotNil(MMLog.shared)
   111.8 +        XCTAssertNotNil(Log.shared)
   111.9      }
  111.10  }
   112.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.2 +++ b/MessageModel/MessageModelTests/Service/VerifiableAccountTest.swift	Mon May 20 16:30:04 2019 +0200
   112.3 @@ -0,0 +1,161 @@
   112.4 +//
   112.5 +//  VerifiableAccountTest.swift
   112.6 +//  pEpForiOSTests
   112.7 +//
   112.8 +//  Created by Dirk Zimmermann on 16.04.19.
   112.9 +//  Copyright © 2019 p≡p Security S.A. All rights reserved.
  112.10 +//
  112.11 +
  112.12 +import XCTest
  112.13 +
  112.14 +import MessageModel
  112.15 +
  112.16 +class VerifiableAccountTest: XCTestCase {
  112.17 +    func testBasicSuccess() {
  112.18 +        let verifier = VerifiableAccount()
  112.19 +        var verifierType: VerifiableAccountProtocol = verifier
  112.20 +        SecretTestData().populateVerifiableAccount(
  112.21 +            verifiableAccount: &verifierType)
  112.22 +        let expDidVerify = expectation(description: "expDidVerify")
  112.23 +        let delegate = VerifiableAccountTestDelegate(expDidVerify: expDidVerify)
  112.24 +        try! check(verifier: &verifierType, delegate: delegate)
  112.25 +        wait(for: [expDidVerify], timeout: TestUtil.waitTime)
  112.26 +
  112.27 +        guard let theResult = delegate.result else {
  112.28 +            XCTFail()
  112.29 +            return
  112.30 +        }
  112.31 +        switch theResult {
  112.32 +        case .success(()):
  112.33 +            break
  112.34 +        case .failure(_):
  112.35 +            XCTFail()
  112.36 +        }
  112.37 +    }
  112.38 +
  112.39 +    func testFailingValidation() {
  112.40 +        let (exceptionOnVerify, exceptionOnSave) = checkFailingValidation() {
  112.41 +            var newOne = $0
  112.42 +            newOne.address = nil
  112.43 +            return newOne
  112.44 +        }
  112.45 +        XCTAssertTrue(exceptionOnVerify)
  112.46 +        XCTAssertTrue(exceptionOnSave)
  112.47 +    }
  112.48 +
  112.49 +    func testBasicFailingVerification() {
  112.50 +        let result = checkBasicVerification() { v in
  112.51 +            var verifiable = v
  112.52 +
  112.53 +            // This should make it fail quickly
  112.54 +            verifiable.serverIMAP = "localhost"
  112.55 +            verifiable.portIMAP = 5
  112.56 +            verifiable.serverSMTP = "localhost"
  112.57 +            verifiable.portSMTP = 5
  112.58 +
  112.59 +            return verifiable
  112.60 +        }
  112.61 +        switch result {
  112.62 +        case .success(_):
  112.63 +            XCTFail()
  112.64 +        case .failure(_):
  112.65 +            break
  112.66 +        }
  112.67 +    }
  112.68 +
  112.69 +    func testBasicFailingVerificationWithWrongPassword() {
  112.70 +        let result = checkBasicVerification() { v in
  112.71 +            var verifiable = v
  112.72 +
  112.73 +            verifiable.password = "xxxxxxxxxx"
  112.74 +
  112.75 +            return verifiable
  112.76 +        }
  112.77 +        switch result {
  112.78 +        case .success(_):
  112.79 +            XCTFail()
  112.80 +        case .failure(_):
  112.81 +            break
  112.82 +        }
  112.83 +    }
  112.84 +
  112.85 +    // MARK: Helpers
  112.86 +
  112.87 +    /// Tries `verify()` and `save()` on the given `VerifiableAccountProtocol`.
  112.88 +    /// - Returns: A tuple of Bool denoting if `verify()` and `save()` threw exceptions.
  112.89 +    func checkFailingValidation(
  112.90 +        modifier: (VerifiableAccountProtocol) -> VerifiableAccountProtocol) -> (Bool, Bool) {
  112.91 +        let verifier = VerifiableAccount()
  112.92 +        var verifierType: VerifiableAccountProtocol = verifier
  112.93 +        SecretTestData().populateVerifiableAccount(
  112.94 +            verifiableAccount: &verifierType)
  112.95 +
  112.96 +        // Invalidate it
  112.97 +        var verifierToBeUsed = modifier(verifierType)
  112.98 +
  112.99 +        var exceptionHit1 = false
 112.100 +        do {
 112.101 +            try check(verifier: &verifierToBeUsed, delegate: nil)
 112.102 +        } catch {
 112.103 +            exceptionHit1 = true
 112.104 +        }
 112.105 +
 112.106 +        var exceptionHit2 = false
 112.107 +        do {
 112.108 +            try check(verifier: &verifierToBeUsed, delegate: nil)
 112.109 +        } catch {
 112.110 +            exceptionHit2 = true
 112.111 +        }
 112.112 +
 112.113 +        return (exceptionHit1, exceptionHit2)
 112.114 +    }
 112.115 +
 112.116 +    func check(verifier: inout VerifiableAccountProtocol,
 112.117 +               delegate: VerifiableAccountDelegate?) throws {
 112.118 +        verifier.verifiableAccountDelegate = delegate
 112.119 +        try verifier.verify()
 112.120 +    }
 112.121 +
 112.122 +    enum TestError: Error {
 112.123 +        case noResult
 112.124 +    }
 112.125 +
 112.126 +    /// Expects a failure, lets caller modify the `VerifiableAccountProtocol`.
 112.127 +    func checkBasicVerification(
 112.128 +        modifier: (VerifiableAccountProtocol) -> VerifiableAccountProtocol)
 112.129 +        -> Result<Void, Error> {
 112.130 +            let verifier = VerifiableAccount()
 112.131 +            var verifiable: VerifiableAccountProtocol = verifier
 112.132 +            SecretTestData().populateVerifiableAccount(
 112.133 +                verifiableAccount: &verifiable)
 112.134 +
 112.135 +            verifiable = modifier(verifiable)
 112.136 +
 112.137 +            let expDidVerify = expectation(description: "expDidVerify")
 112.138 +            let delegate = VerifiableAccountTestDelegate(expDidVerify: expDidVerify)
 112.139 +            try! check(verifier: &verifiable, delegate: delegate)
 112.140 +            wait(for: [expDidVerify], timeout: TestUtil.waitTime)
 112.141 +
 112.142 +            guard let result = delegate.result else {
 112.143 +                XCTFail()
 112.144 +                return .failure(TestError.noResult)
 112.145 +            }
 112.146 +
 112.147 +            return result
 112.148 +    }
 112.149 +}
 112.150 +
 112.151 +class VerifiableAccountTestDelegate: VerifiableAccountDelegate {
 112.152 +    var result: Result<Void, Error>?
 112.153 +
 112.154 +    let expDidVerify: XCTestExpectation
 112.155 +
 112.156 +    init(expDidVerify: XCTestExpectation) {
 112.157 +        self.expDidVerify = expDidVerify
 112.158 +    }
 112.159 +
 112.160 +    func didEndVerification(result: Result<Void, Error>) {
 112.161 +        self.result = result
 112.162 +        expDidVerify.fulfill()
 112.163 +    }
 112.164 +}
   113.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.2 +++ b/MessageModel/MessageModelTests/Util/MimeTypeUtilsTest.swift	Mon May 20 16:30:04 2019 +0200
   113.3 @@ -0,0 +1,118 @@
   113.4 +//
   113.5 +//  MimeTypeUtilsTest.swift
   113.6 +//  MessageModelTests
   113.7 +//
   113.8 +//  Created by Alejandro Gelos on 08/05/2019.
   113.9 +//  Copyright © 2019 pEp Security S.A. All rights reserved.
  113.10 +//
  113.11 +
  113.12 +import XCTest
  113.13 +@testable import MessageModel
  113.14 +
  113.15 +class MimeTypeUtilsTest: XCTestCase {
  113.16 +    private var mimeTypeUtils: MimeTypeUtils?
  113.17 +
  113.18 +    override func setUp() {
  113.19 +        super.setUp()
  113.20 +        mimeTypeUtils = MimeTypeUtils()
  113.21 +    }
  113.22 +
  113.23 +    override func tearDown() {
  113.24 +        mimeTypeUtils = nil
  113.25 +        super.tearDown()
  113.26 +    }
  113.27 +
  113.28 +    func testInit() {
  113.29 +        guard let _ = MimeTypeUtils() else {
  113.30 +            XCTFail()
  113.31 +            return
  113.32 +        }
  113.33 +    }
  113.34 +
  113.35 +    func testMimeTypeFromFileExtension() {
  113.36 +        // Given
  113.37 +        guard let mimetypeUtils = mimeTypeUtils else {
  113.38 +            XCTFail()
  113.39 +            return
  113.40 +        }
  113.41 +
  113.42 +        let fileExtension = ["h261", "ps", "aas", "abw", "acc", "ace", "acu", "acx", "adp", "jpg"]
  113.43 +
  113.44 +        let expectedMimeTypes = ["video/h261", "application/postscript",
  113.45 +                            "application/x-authorware-seg", "application/x-abiword",
  113.46 +                            "application/vnd.americandynamics.acc", "application/x-ace-compressed",
  113.47 +                            "application/vnd.acucobol", "application/internet-property-stream",
  113.48 +                            "audio/adpcm", "image/jpeg"]
  113.49 +        // When
  113.50 +        let mimeTypes = fileExtension.map { mimetypeUtils.mimeType(fromFileExtension: $0) }
  113.51 +
  113.52 +        // Then
  113.53 +        XCTAssertEqual(mimeTypes, expectedMimeTypes)
  113.54 +    }
  113.55 +
  113.56 +    func testFileExtensionFromMimeType() {
  113.57 +        // Given
  113.58 +        guard let mimetypeUtils = mimeTypeUtils else {
  113.59 +            XCTFail()
  113.60 +            return
  113.61 +        }
  113.62 +        let mimeTypes = ["video/h261", "application/vnd.americandynamics.acc",
  113.63 +                         "application/x-ace-compressed", "application/vnd.acucobol",
  113.64 +                         "application/internet-property-stream", "audio/adpcm", "image/jpeg"]
  113.65 +
  113.66 +        let expectedFileExtension = ["h261", "acc","ace", "acu", "acx", "adp", "jpg"]
  113.67 +        // When
  113.68 +        let fileExtension = mimeTypes.map { mimetypeUtils.fileExtension(fromMimeType: $0) }
  113.69 +
  113.70 +        // Then
  113.71 +        XCTAssertEqual(fileExtension, expectedFileExtension)
  113.72 +    }
  113.73 +
  113.74 +    func testMimeTypeFromURL() {
  113.75 +        // Given
  113.76 +        guard let mimetypeUtils = mimeTypeUtils,
  113.77 +              let sampleURL = URL(string: "www.google.jpg") else {
  113.78 +            XCTFail()
  113.79 +            return
  113.80 +        }
  113.81 +        let expectedMimeType = "image/jpeg"
  113.82 +
  113.83 +        // When
  113.84 +        let mimeType = mimetypeUtils.mimeType(fromURL: sampleURL)
  113.85 +
  113.86 +        // Then
  113.87 +        XCTAssertEqual(mimeType, expectedMimeType)
  113.88 +    }
  113.89 +
  113.90 +    func testIsImageFromMimeTypeWithImagesMimeTypes() {
  113.91 +        // Given
  113.92 +        guard let mimetypeUtils = mimeTypeUtils else {
  113.93 +            XCTFail()
  113.94 +            return
  113.95 +        }
  113.96 +        let imageMimeTypes = ["image/png", "image/jpeg", "image/gif"]
  113.97 +
  113.98 +        // When
  113.99 +        let areImages = imageMimeTypes.map { mimetypeUtils.isImage(mimeType: $0) }
 113.100 +
 113.101 +        // Then
 113.102 +        areImages.map { XCTAssertTrue($0) }
 113.103 +    }
 113.104 +
 113.105 +    func testIsImageFromMimeTypeWithOutImagesMimeTypes() {
 113.106 +        // Given
 113.107 +        guard let mimetypeUtils = mimeTypeUtils else {
 113.108 +            XCTFail()
 113.109 +            return
 113.110 +        }
 113.111 +        let noImageMimeTypes = ["video/h261", "application/vnd.americandynamics.acc",
 113.112 +                                "application/x-ace-compressed", "application/vnd.acucobol",
 113.113 +                                "application/internet-property-stream", "audio/adpcm"]
 113.114 +
 113.115 +        // When
 113.116 +        let areImages = noImageMimeTypes.map { mimetypeUtils.isImage(mimeType: $0) }
 113.117 +
 113.118 +        // Then
 113.119 +        areImages.map { XCTAssertFalse($0) }
 113.120 +    }
 113.121 +}
   114.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.2 +++ b/MessageModel/MessageModelTests/Util/TestDataBase.swift	Mon May 20 16:30:04 2019 +0200
   114.3 @@ -0,0 +1,409 @@
   114.4 +//
   114.5 +//  TestData.swift
   114.6 +//  pEpForiOS
   114.7 +//
   114.8 +//  Created by Dirk Zimmermann on 02/11/16.
   114.9 +//  Copyright © 2016 p≡p Security S.A. All rights reserved.
  114.10 +//
  114.11 +
  114.12 +import UIKit
  114.13 +import CoreData
  114.14 +
  114.15 +import MessageModel
  114.16 +import PEPObjCAdapterFramework
  114.17 +import PantomimeFramework
  114.18 +
  114.19 +/// Base class for test data.
  114.20 +/// - Note:
  114.21 +///   1. This class is used both in MessageModel and the app,
  114.22 +///      so it's _duplicated code_ for the testing targets.
  114.23 +///   2. Make sure that, in your SecretTestData, you override:
  114.24 +///      * `populateAccounts` if you don't use the greenmail local server for testing,
  114.25 +///        or you want to test against other servers for various reasons.
  114.26 +///      * `populateVerifiableAccounts` in order to provide verifiable servers, to test
  114.27 +///        the verification parts.
  114.28 +class TestDataBase {
  114.29 +    struct AccountSettings {
  114.30 +        var accountName: String?
  114.31 +        var idAddress: String
  114.32 +        var idUserName: String?
  114.33 +        var smtpLoginName: String?
  114.34 +        var smtpServerAddress: String
  114.35 +        var smtpServerType: Server.ServerType = .smtp
  114.36 +        var smtpServerTransport: Server.Transport = .tls
  114.37 +        var smtpServerPort: UInt16 = 587
  114.38 +        var imapLoginName: String?
  114.39 +        var imapServerAddress: String
  114.40 +        var imapServerType: Server.ServerType = .imap
  114.41 +        var imapServerTransport: Server.Transport = .startTls
  114.42 +        var imapServerPort: UInt16 = 993
  114.43 +        var password: String?
  114.44 +
  114.45 +        init(accountName: String,
  114.46 +             idAddress: String,
  114.47 +             idUserName: String,
  114.48 +             imapLoginName: String? = nil,
  114.49 +             imapServerAddress: String,
  114.50 +             imapServerType: Server.ServerType,
  114.51 +             imapServerTransport: Server.Transport,
  114.52 +             imapServerPort: UInt16,
  114.53 +             smtpLoginName: String? = nil,
  114.54 +             smtpServerAddress: String,
  114.55 +             smtpServerType: Server.ServerType,
  114.56 +             smtpServerTransport: Server.Transport,
  114.57 +             smtpServerPort: UInt16,
  114.58 +             password: String) {
  114.59 +            self.accountName = accountName
  114.60 +            self.idAddress = idAddress
  114.61 +            self.idUserName = idUserName
  114.62 +            self.smtpLoginName = smtpLoginName
  114.63 +            self.smtpServerAddress = smtpServerAddress
  114.64 +            self.smtpServerType = smtpServerType
  114.65 +            self.smtpServerTransport = smtpServerTransport
  114.66 +            self.smtpServerPort = smtpServerPort
  114.67 +            self.imapLoginName = imapLoginName
  114.68 +            self.imapServerAddress = imapServerAddress
  114.69 +            self.imapServerType = imapServerType
  114.70 +            self.imapServerTransport = imapServerTransport
  114.71 +            self.imapServerPort = imapServerPort
  114.72 +            self.password = password
  114.73 +        }
  114.74 +
  114.75 +        func cdAccount() -> CdAccount {
  114.76 +            let id = CdIdentity.create()
  114.77 +            id.address = idAddress
  114.78 +            id.userName = idUserName
  114.79 +            id.userID = CdIdentity.pEpOwnUserID
  114.80 +
  114.81 +            let acc = CdAccount.create()
  114.82 +            acc.identity = id
  114.83 +
  114.84 +            //SMTP
  114.85 +            let smtp = CdServer.create()
  114.86 +            smtp.serverType = smtpServerType
  114.87 +            smtp.port = NSNumber(value: smtpServerPort)
  114.88 +            smtp.address = smtpServerAddress
  114.89 +            smtp.transport = smtpServerTransport
  114.90 +
  114.91 +            let keySmtp = MessageID.generate()
  114.92 +            CdServerCredentials.add(password: password, forKey: keySmtp)
  114.93 +            let credSmtp = CdServerCredentials.create()
  114.94 +            credSmtp.loginName = smtpLoginName ?? id.address
  114.95 +            credSmtp.key = keySmtp
  114.96 +            smtp.credentials = credSmtp
  114.97 +
  114.98 +            acc.addToServers(smtp)
  114.99 +
 114.100 +            //IMAP
 114.101 +            let imap = CdServer.create()
 114.102 +            imap.serverType = imapServerType
 114.103 +            imap.port = NSNumber(value: imapServerPort)
 114.104 +            imap.address = imapServerAddress
 114.105 +            imap.transport = imapServerTransport
 114.106 +
 114.107 +            let keyImap = MessageID.generate()
 114.108 +            CdServerCredentials.add(password: password, forKey: keyImap)
 114.109 +            let credImap = CdServerCredentials.create()
 114.110 +            credImap.loginName = imapLoginName ?? id.address
 114.111 +            credImap.key = keyImap
 114.112 +            imap.credentials = credImap
 114.113 +
 114.114 +            acc.addToServers(imap)
 114.115 +
 114.116 +            return acc
 114.117 +        }
 114.118 +
 114.119 +        func cdIdentityWithoutAccount(isMyself: Bool = false) -> CdIdentity {
 114.120 +            let id = CdIdentity.create()
 114.121 +            id.address = idAddress
 114.122 +            id.userName = idUserName
 114.123 +            if isMyself {
 114.124 +                id.userID = CdIdentity.pEpOwnUserID
 114.125 +            } else {
 114.126 +                id.userID = UUID().uuidString
 114.127 +            }
 114.128 +            return id
 114.129 +        }
 114.130 +
 114.131 +        func account() -> Account {
 114.132 +            let id = Identity.create(address: idAddress, userName: idUserName, isMySelf: true)
 114.133 +
 114.134 +            let credSmtp = ServerCredentials.create(loginName: id.address)
 114.135 +            credSmtp.password = password
 114.136 +            let smtp = Server.create(serverType: .smtp,
 114.137 +                                     port: smtpServerPort,
 114.138 +                                     address: smtpServerAddress,
 114.139 +                                     transport: smtpServerTransport,
 114.140 +                                     credentials:credSmtp)
 114.141 +
 114.142 +            let credImap = ServerCredentials.create(loginName: id.address)
 114.143 +            credImap.password = password
 114.144 +            let imap = Server.create(serverType: .imap,
 114.145 +                                     port: imapServerPort,
 114.146 +                                     address: imapServerAddress,
 114.147 +                                     transport: imapServerTransport,
 114.148 +                                     credentials:credImap)
 114.149 +            
 114.150 +            let acc = Account(user: id, servers: [smtp, imap])
 114.151 +
 114.152 +            return acc
 114.153 +        }
 114.154 +
 114.155 +        func pEpIdentity() -> PEPIdentity {
 114.156 +            let ident = PEPIdentity(address: idAddress)
 114.157 +            ident.userName = accountName
 114.158 +            return ident
 114.159 +        }
 114.160 +
 114.161 +        func basicConnectInfo(emailProtocol: EmailProtocol) -> BasicConnectInfo {
 114.162 +            return BasicConnectInfo(
 114.163 +                accountEmailAddress: idAddress,
 114.164 +                loginName: imapLoginName ?? idAddress,
 114.165 +                loginPassword: password,
 114.166 +                accessToken: nil,
 114.167 +                networkAddress: imapServerAddress,
 114.168 +                networkPort: imapServerPort,
 114.169 +                connectionTransport: ConnectionTransport(transport: imapServerTransport),
 114.170 +                authMethod: nil,
 114.171 +                emailProtocol: emailProtocol)
 114.172 +        }
 114.173 +
 114.174 +        func basicConnectInfoIMAP() -> BasicConnectInfo {
 114.175 +            return basicConnectInfo(emailProtocol: .imap)
 114.176 +        }
 114.177 +
 114.178 +        func basicConnectInfoSMTP() -> BasicConnectInfo {
 114.179 +            return basicConnectInfo(emailProtocol: .smtp)
 114.180 +        }
 114.181 +
 114.182 +        /// Transfers the account data into a `VerifiableAccountProtocol`
 114.183 +        /// that you then can verify the acconut data with.
 114.184 +        func populate(verifiableAccount: inout VerifiableAccountProtocol) {
 114.185 +            verifiableAccount.userName = accountName
 114.186 +            verifiableAccount.address = idAddress
 114.187 +            verifiableAccount.loginName = imapLoginName
 114.188 +            verifiableAccount.accessToken = nil
 114.189 +            verifiableAccount.password = password
 114.190 +
 114.191 +            verifiableAccount.serverIMAP = imapServerAddress
 114.192 +            verifiableAccount.portIMAP = imapServerPort
 114.193 +            verifiableAccount.transportIMAP = ConnectionTransport(transport: imapServerTransport)
 114.194 +
 114.195 +            verifiableAccount.serverSMTP = smtpServerAddress
 114.196 +            verifiableAccount.portSMTP = smtpServerPort
 114.197 +            verifiableAccount.transportSMTP = ConnectionTransport(transport: smtpServerTransport)
 114.198 +
 114.199 +            verifiableAccount.authMethod = nil
 114.200 +        }
 114.201 +    }
 114.202 +
 114.203 +    private var testAccounts = [AccountSettings]()
 114.204 +    private var verifiableTestAccounts = [AccountSettings]()
 114.205 +
 114.206 +    func append(accountSettings: AccountSettings) {
 114.207 +        testAccounts.append(accountSettings)
 114.208 +    }
 114.209 +
 114.210 +    func append(verifiableAccountSettings: AccountSettings) {
 114.211 +        verifiableTestAccounts.append(verifiableAccountSettings)
 114.212 +    }
 114.213 +
 114.214 +    /**
 114.215 +     Add IMAP/SMTP accounts that are used for testing.
 114.216 +     - Note:
 114.217 +       * These (local) accounts depend on a local greenmail server.
 114.218 +         Please see the readme for details.
 114.219 +       * Override this in SecretTestData if needed, for testing external servers.
 114.220 +       * The first 2 accounts play in tandem for some tests.
 114.221 +       * Some tests send emails to unittest.ios.1@peptest.ch,
 114.222 +         this account has to exist but there's no need to query it.
 114.223 +     */
 114.224 +    func populateAccounts() {
 114.225 +        addLocalTestAccount(userName: "test001")
 114.226 +        addLocalTestAccount(userName: "test002")
 114.227 +        addLocalTestAccount(userName: "test003")
 114.228 +    }
 114.229 +
 114.230 +    /**
 114.231 +     Accounts needed for testing LAS, that is they need to be registered
 114.232 +     in the LAS DB or provide (correct) DNS SRV for IMAP and SMTP.
 114.233 +     - Note: Override this in your SecretTestData to something that's working.
 114.234 +     */
 114.235 +    func populateVerifiableAccounts() {
 114.236 +        append(verifiableAccountSettings: AccountSettings(
 114.237 +            accountName: "Whatever_you_want",
 114.238 +            idAddress: "whatever_you_want@yahoo.com",
 114.239 +            idUserName: "whatever_you_want@yahoo.com",
 114.240 +
 114.241 +            imapServerAddress: "imap.mail.yahoo.com",
 114.242 +            imapServerType: Server.ServerType.imap,
 114.243 +            imapServerTransport: Server.Transport.tls,
 114.244 +            imapServerPort: 993,
 114.245 +
 114.246 +            smtpServerAddress: "smtp.mail.yahoo.com",
 114.247 +            smtpServerType: Server.ServerType.smtp,
 114.248 +            smtpServerTransport: Server.Transport.tls,
 114.249 +            smtpServerPort: 465,
 114.250 +
 114.251 +            password: "whatever_you_want"))
 114.252 +
 114.253 +        fatalError("Abstract method. Must be overridden")
 114.254 +    }
 114.255 +
 114.256 +    private func addLocalTestAccount(userName: String) {
 114.257 +        let address = "\(userName)@localhost"
 114.258 +        append(accountSettings: AccountSettings(
 114.259 +            accountName: "Unit Test \(address)",
 114.260 +            idAddress: address,
 114.261 +            idUserName: "User \(address)",
 114.262 +
 114.263 +            imapLoginName: userName,
 114.264 +            imapServerAddress: "localhost",
 114.265 +            imapServerType: Server.ServerType.imap,
 114.266 +            imapServerTransport: Server.Transport.plain,
 114.267 +            imapServerPort: 3143,
 114.268 +
 114.269 +            smtpLoginName: userName,
 114.270 +            smtpServerAddress: "localhost",
 114.271 +            smtpServerType: Server.ServerType.smtp,
 114.272 +            smtpServerTransport: Server.Transport.plain,
 114.273 +            smtpServerPort: 3025,
 114.274 +
 114.275 +            password: "pwd"))
 114.276 +    }
 114.277 +
 114.278 +    /**
 114.279 +     - Returns: A valid `CdAccount`.
 114.280 +     */
 114.281 +    func createWorkingCdAccount(number: Int = 0) -> CdAccount {
 114.282 +        let result = createWorkingAccountSettings(number: number).cdAccount()
 114.283 +        // The identity of an account is mySelf by definion.
 114.284 +        result.identity?.userID = CdIdentity.pEpOwnUserID
 114.285 +        return result
 114.286 +    }
 114.287 +
 114.288 +    /**
 114.289 +     - Returns: A valid `CdAccount`.
 114.290 +     */
 114.291 +    func createVerifiableCdAccount(number: Int = 0) -> CdAccount {
 114.292 +        let result = createVerifiableAccountSettings(number: number).cdAccount()
 114.293 +        // The identity of an account is mySelf by definion.
 114.294 +        result.identity?.userID = CdIdentity.pEpOwnUserID
 114.295 +        return result
 114.296 +    }
 114.297 +
 114.298 +    /**
 114.299 +     - Returns: A valid `BasicConnectInfo` for IMAP.
 114.300 +     */
 114.301 +    func createVerifiableBasicConnectInfoIMAP(number: Int = 0) -> BasicConnectInfo {
 114.302 +        return createVerifiableAccountSettings(number: number).basicConnectInfoIMAP()
 114.303 +    }
 114.304 +
 114.305 +    /**
 114.306 +     - Returns: A valid `BasicConnectInfo` for SMTP.
 114.307 +     */
 114.308 +    func createVerifiableBasicConnectInfoSMTP(number: Int = 0) -> BasicConnectInfo {
 114.309 +        return createVerifiableAccountSettings(number: number).basicConnectInfoSMTP()
 114.310 +    }
 114.311 +
 114.312 +    /**
 114.313 +     - Returns: A valid `CdIdentity` without parent account.
 114.314 +     */
 114.315 +    func createWorkingCdIdentity(number: Int = 0, isMyself: Bool = false) -> CdIdentity {
 114.316 +        let result = createWorkingAccountSettings(number: number).cdIdentityWithoutAccount(isMyself: isMyself)
 114.317 +        return result
 114.318 +    }
 114.319 +
 114.320 +    /**
 114.321 +     - Returns: A `CdAccount` that should not be able to be verified.
 114.322 +     */
 114.323 +    func createDisfunctionalCdAccount() -> CdAccount {
 114.324 +        var accountSettings = createWorkingAccountSettings(number: 0)
 114.325 +        accountSettings.smtpServerAddress = "localhost"
 114.326 +        accountSettings.smtpServerPort = 2323
 114.327 +        accountSettings.imapServerPort = 2323
 114.328 +        accountSettings.imapServerAddress = "localhost"
 114.329 +        return accountSettings.cdAccount()
 114.330 +    }
 114.331 +
 114.332 +    func createWorkingAccountSettings(number: Int = 0) -> AccountSettings {
 114.333 +        populateAccounts()
 114.334 +        return testAccounts[number]
 114.335 +    }
 114.336 +
 114.337 +    func createVerifiableAccountSettings(number: Int = 0) -> AccountSettings {
 114.338 +        populateVerifiableAccounts()
 114.339 +        return verifiableTestAccounts[number]
 114.340 +    }
 114.341 +
 114.342 +    /**
 114.343 +     - Returns: A valid `Account`.
 114.344 +     */
 114.345 +    func createWorkingAccount(number: Int = 0) -> Account {
 114.346 +        return createWorkingAccountSettings(number: number).account()
 114.347 +    }
 114.348 +
 114.349 +    /**
 114.350 +     - Returns: A valid `Account`.
 114.351 +     */
 114.352 +    func createVerifiableAccount(number: Int = 0) -> Account {
 114.353 +        return createVerifiableAccountSettings(number: number).account()
 114.354 +    }
 114.355 +
 114.356 +    /**
 114.357 +     - Returns: A valid `PEPIdentity`.
 114.358 +     */
 114.359 +    func createWorkingIdentity(number: Int = 0, isMyself: Bool = false) -> PEPIdentity {
 114.360 +        populateAccounts()
 114.361 +        return createWorkingCdIdentity(number: number, isMyself: isMyself).pEpIdentity()
 114.362 +    }
 114.363 +
 114.364 +    /**
 114.365 +     - Returns: An `AccountSettings` object with an SMTP server that should yield a quick timeout.
 114.366 +     */
 114.367 +    func createSmtpTimeOutAccountSettings() -> AccountSettings {
 114.368 +        populateAccounts()
 114.369 +        var accountSettings = createVerifiableAccountSettings(number: 0)
 114.370 +        accountSettings.smtpServerAddress = "localhost"
 114.371 +        accountSettings.smtpServerPort = 2323
 114.372 +        return accountSettings
 114.373 +    }
 114.374 +
 114.375 +    /**
 114.376 +     - Returns: An `AccountSettings` object with an IMAP server that should yield a quick timeout.
 114.377 +     */
 114.378 +    func createImapTimeOutAccountSettings() -> AccountSettings {
 114.379 +        populateAccounts()
 114.380 +        var accountSettings = createWorkingAccountSettings(number: 0)
 114.381 +        accountSettings.imapServerAddress = "localhost"
 114.382 +        accountSettings.imapServerPort = 2323
 114.383 +        return accountSettings
 114.384 +    }
 114.385 +
 114.386 +    /**
 114.387 +     - Returns: A `CdAccount` around `createSmtpTimeOutAccountSettings`.
 114.388 +     */
 114.389 +    func createSmtpTimeOutCdAccount() -> CdAccount {
 114.390 +        return createSmtpTimeOutAccountSettings().cdAccount()
 114.391 +    }
 114.392 +
 114.393 +    /**
 114.394 +     - Returns: An `Account` around `createSmtpTimeOutAccountSettings`.
 114.395 +     */
 114.396 +    func createSmtpTimeOutAccount() -> Account {
 114.397 +        return createSmtpTimeOutAccountSettings().account()
 114.398 +    }
 114.399 +
 114.400 +    /**
 114.401 +     - Returns: An `Account` around `createImapTimeOutAccountSettings`.
 114.402 +     */
 114.403 +    func createImapTimeOutAccount() -> Account {
 114.404 +        return createImapTimeOutAccountSettings().account()
 114.405 +    }
 114.406 +
 114.407 +    func populateVerifiableAccount(number: Int = 0,
 114.408 +                                   verifiableAccount: inout VerifiableAccountProtocol) {
 114.409 +        createVerifiableAccountSettings(number: number).populate(
 114.410 +            verifiableAccount: &verifiableAccount)
 114.411 +    }
 114.412 +}