merge refactor IOS-1558
authorAlejandro Gelos <alejandro@pep-project.org>
Fri, 17 May 2019 14:16:55 +0200
branchIOS-1558
changeset 8670949a6fcdbbf9
parent 8524 4d1867c9ca79
parent 8669 e16f27101ac0
child 8671 0eac048db37e
merge refactor
Submodules/pEpIOSToolbox/pEpIOSToolbox/Other/Constants.swift
pEpForiOS/Models/VerifiableAccount/BasicConnectInfo+VerifiableAccount.swift
pEpForiOS/Models/VerifiableAccount/VerifiableAccount.swift
pEpForiOS/Models/VerifiableAccount/VerifiableAccountIMAP.swift
pEpForiOS/Models/VerifiableAccount/VerifiableAccountProtocol+UI.swift
pEpForiOS/Models/VerifiableAccount/VerifiableAccountSMTP.swift
pEpForiOS/Util/Extensions/URL+MIME.swift
pEpForiOS/Util/jsonMimeType.txt
pEpForiOSTests/AccountVerificationServiceTests.swift
pEpForiOSTests/Service/VerifiableAccountTest.swift
subModules/pEpIOSToolbox/pEpIOSToolbox.xcodeproj/project.pbxproj
     1.1 --- a/.hgignore	Wed May 08 12:31:03 2019 +0200
     1.2 +++ b/.hgignore	Fri May 17 14:16:55 2019 +0200
     1.3 @@ -1,4 +1,4 @@
     1.4 -regexp
     1.5 +syntax: regexp
     1.6  \.DS_Store
     1.7  xcuserdata/.*
     1.8  Pods/.*
     1.9 @@ -9,10 +9,6 @@
    1.10  pEpTrustWords\.bundle/system\.db
    1.11  build/.*
    1.12  
    1.13 -.*secret.*
    1.14 -.*Secret.*
    1.15 -.*SECRET.*
    1.16 -
    1.17  ^.*\.pyc$
    1.18  
    1.19 -glob
    1.20 +syntax: glob
     2.1 --- a/README.md	Wed May 08 12:31:03 2019 +0200
     2.2 +++ b/README.md	Fri May 17 14:16:55 2019 +0200
     2.3 @@ -86,10 +86,10 @@
     2.4  java -Dgreenmail.setup.test.all -Dgreenmail.users=test001:pwd@localhost,test002:pwd@localhost,test003:pwd@localhost -jar ~/Downloads/greenmail-standalone-1.5.9.jar
     2.5  ```
     2.6  
     2.7 -The non-existing file referenced in the unit test project, ./pEpForiOSTests/TestUtil/SecretTestData.swift, must be
     2.8 +The non-existing file referenced in the unit test project, pEpForiOSTests/../pEp_for_iOS_intern/SecretTestData.swift, must be
     2.9  created, with a class named SecretTestData, derived from TestDataBase.
    2.10  
    2.11 -In `SecretTestData.swift`, you must override `populateVerifiableAccounts`, adding servers that are either registered in the LAS database or provide DNS SRV for IMAP and SMTP in order to test the "automatic account login".
    2.12 +In `SecretTestData.swift`, you must at least override `populateVerifiableAccounts`, adding servers that are either registered in the LAS database or provide DNS SRV for IMAP and SMTP in order to test the "automatic account login".
    2.13  
    2.14  If you want to run the tests against your own servers, override `populateAccounts` accordingly.
    2.15  
    2.16 @@ -102,13 +102,13 @@
    2.17  
    2.18  ### secret.xcconfig (needed for OAuth2 config secrects and others)
    2.19  
    2.20 -Create secret.xcconfig @ pEpForiOS/secret.xcconfig, with those contents:
    2.21 +Create secret.xcconfig @ pEpForiOS/../pEp_for_iOS_intern/secret.xcconfig, with those contents:
    2.22  
    2.23  ```
    2.24 -OAUTH2_GMAIL_CLIENT_ID = some_content
    2.25 -OAUTH2_GMAIL_REDIRECT_URL_SCHEME = some_content
    2.26 +OAUTH2_GMAIL_CLIENT_ID = your_secret_content
    2.27 +OAUTH2_GMAIL_REDIRECT_URL_SCHEME = your_secret_content
    2.28  
    2.29 -OAUTH2_YAHOO_CLIENT_ID = some_content
    2.30 +OAUTH2_YAHOO_CLIENT_ID = your_secret_content
    2.31  OAUTH2_YAHOO_CLIENT_SECRET = some_content
    2.32  
    2.33  ```
     3.1 --- a/Submodules/pEpIOSToolbox/pEpIOSToolbox/Other/Constants.swift	Wed May 08 12:31:03 2019 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,52 +0,0 @@
     3.4 -//
     3.5 -//  Constants.swift
     3.6 -//  pEpIOSToolbox
     3.7 -//
     3.8 -//  Created by Dirk Zimmermann on 22.02.19.
     3.9 -//  Copyright © 2019 pEp Security SA. All rights reserved.
    3.10 -//
    3.11 -
    3.12 -import Foundation
    3.13 -
    3.14 -public struct Constants {
    3.15 -    /** MIME content type for plain text */
    3.16 -    public static let contentTypeText = "text/plain"
    3.17 -
    3.18 -    /** MIME content type for HTML */
    3.19 -    public static let contentTypeHtml = "text/html"
    3.20 -
    3.21 -    /**
    3.22 -     Mime type for the "Version" attachment of PGP/MIME.
    3.23 -     */
    3.24 -    public static let contentTypePGPEncrypted = "application/pgp-encrypted"
    3.25 -
    3.26 -    /**
    3.27 -     Content type for MIME multipart/mixed.
    3.28 -     */
    3.29 -    public static let contentTypeMultipartMixed = "multipart/mixed"
    3.30 -
    3.31 -    /**
    3.32 -     Content type for MIME multipart/related.
    3.33 -     */
    3.34 -    public static let contentTypeMultipartRelated = "multipart/related"
    3.35 -
    3.36 -    /**
    3.37 -     Content type for MIME multipart/encrypted.
    3.38 -     */
    3.39 -    public static let contentTypeMultipartEncrypted = "multipart/encrypted"
    3.40 -
    3.41 -    /**
    3.42 -     Protocol for PGP/MIME application/pgp-encrypted.
    3.43 -     */
    3.44 -    public static let protocolPGPEncrypted = "application/pgp-encrypted"
    3.45 -
    3.46 -    /**
    3.47 -     Content type for MIME multipart/alternative.
    3.48 -     */
    3.49 -    public static let contentTypeMultipartAlternative = "multipart/alternative"
    3.50 -
    3.51 -    /**
    3.52 -     The MIME type for attached emails (e.g., when forwarding).
    3.53 -     */
    3.54 -    public static let attachedEmailMimeType = "message/rfc822"
    3.55 -}
     4.1 --- a/pEpForiOS.xcodeproj/project.pbxproj	Wed May 08 12:31:03 2019 +0200
     4.2 +++ b/pEpForiOS.xcodeproj/project.pbxproj	Fri May 17 14:16:55 2019 +0200
     4.3 @@ -26,7 +26,6 @@
     4.4  		0033C08320D7F41600224E61 /* ThreadedEmailViewModelDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0033C08220D7F41600224E61 /* ThreadedEmailViewModelDelegate.swift */; };
     4.5  		0038494A20D25576008000EA /* ProfilePictureComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0038494920D25576008000EA /* ProfilePictureComposer.swift */; };
     4.6  		0038494C20D2587F008000EA /* PepPictureComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0038494B20D2587F008000EA /* PepPictureComposer.swift */; };
     4.7 -		003C0FA720B5581A0093A987 /* SecretTestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003C0FA620B5581A0093A987 /* SecretTestData.swift */; };
     4.8  		004422C82179E3C500BDF6DF /* SettingsCellViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 004422C72179E3C500BDF6DF /* SettingsCellViewModelTest.swift */; };
     4.9  		004422CA2179ECD600BDF6DF /* PassiveModeViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 004422C92179ECD600BDF6DF /* PassiveModeViewModelTest.swift */; };
    4.10  		004422D9217A25AD00BDF6DF /* UnencryptedSubjectViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 004422D8217A25AD00BDF6DF /* UnencryptedSubjectViewModelTest.swift */; };
    4.11 @@ -118,7 +117,6 @@
    4.12  		15410D252199ECD700BBF65F /* AttachmentViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15410D242199ECD700BBF65F /* AttachmentViewModelTest.swift */; };
    4.13  		1541D7ED1FC81D4200D52A5D /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1541D7EC1FC81D4200D52A5D /* URL+Extensions.swift */; };
    4.14  		1541D7F01FC81ED900D52A5D /* URL+ExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1541D7EF1FC81ED900D52A5D /* URL+ExtensionsTest.swift */; };
    4.15 -		1541D7F31FC8292D00D52A5D /* URL+MIME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1541D7F21FC8292D00D52A5D /* URL+MIME.swift */; };
    4.16  		1541D7F51FC82A4900D52A5D /* URL+MIME.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1541D7F41FC82A4900D52A5D /* URL+MIME.swift */; };
    4.17  		1544BD0221524C9F0075C5A0 /* AttachmentFilterTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1544BD0121524C9F0075C5A0 /* AttachmentFilterTest.swift */; };
    4.18  		154D92CF20AC1745009A5868 /* MoveToFolderOperationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 154D92CE20AC1744009A5868 /* MoveToFolderOperationTest.swift */; };
    4.19 @@ -203,6 +201,7 @@
    4.20  		430E0BE71EAF5E2600378EC2 /* NSMutableDictionary+pEp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430E0BE61EAF5E2600378EC2 /* NSMutableDictionary+pEp.swift */; };
    4.21  		430E5F201EBC87A700E5D5D3 /* LanguageListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430E5F1F1EBC87A700E5D5D3 /* LanguageListTableViewCell.swift */; };
    4.22  		43106A192045716000693144 /* OAuth2ConfigurationProtocol+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43106A182045716000693144 /* OAuth2ConfigurationProtocol+Extension.swift */; };
    4.23 +		4312BE89228439670002129D /* SecretUITestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4312BE88228439670002129D /* SecretUITestData.swift */; };
    4.24  		431394A91E4B03AA00D92F33 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 431394A81E4B03AA00D92F33 /* Settings.bundle */; };
    4.25  		4315E4C3201242BB00F68763 /* OAuth2Type+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4315E4C2201242BB00F68763 /* OAuth2Type+Extension.swift */; };
    4.26  		431798771CF87FE6007DD655 /* ReferenceCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431798761CF87FE6007DD655 /* ReferenceCounter.swift */; };
    4.27 @@ -212,7 +211,6 @@
    4.28  		431C6E041FE7A85200E23BE0 /* OAuth2ConfigurationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431C6E031FE7A85200E23BE0 /* OAuth2ConfigurationProtocol.swift */; };
    4.29  		431D60DB1E93BB2D001266D7 /* AttachmentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431D60DA1E93BB2D001266D7 /* AttachmentsView.swift */; };
    4.30  		431D60DD1E93D580001266D7 /* MessageAttachmentsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431D60DC1E93D580001266D7 /* MessageAttachmentsCell.swift */; };
    4.31 -		431E58FC1ED5926B00EFA77F /* AccountVerificationServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431E58FB1ED5926B00EFA77F /* AccountVerificationServiceTests.swift */; };
    4.32  		431E65631EEAE65200B8BBFC /* HandshakeUITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431E65621EEAE65200B8BBFC /* HandshakeUITest.swift */; };
    4.33  		431E8F7E1CFDCF3A00C33647 /* EmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431E8F7D1CFDCF3A00C33647 /* EmailViewController.swift */; };
    4.34  		431F987F1F6FD3E300A1E4D2 /* HandshakePartnerTableViewCellViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431F987E1F6FD3E300A1E4D2 /* HandshakePartnerTableViewCellViewModelTests.swift */; };
    4.35 @@ -276,15 +274,14 @@
    4.36  		4356FFEC21356CB600804089 /* ReplyAllPossibleCheckerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4356FFEB21356CB600804089 /* ReplyAllPossibleCheckerTest.swift */; };
    4.37  		435F7C75215E05DA00F21EFD /* 1364_Mail_missing_attached_image.txt in Resources */ = {isa = PBXBuildFile; fileRef = 435F7C74215E05DA00F21EFD /* 1364_Mail_missing_attached_image.txt */; };
    4.38  		43628766213D7A5E0066CD03 /* IOS-1300_odt_attachment.txt in Resources */ = {isa = PBXBuildFile; fileRef = 43628765213D7A5E0066CD03 /* IOS-1300_odt_attachment.txt */; };
    4.39 -		4365E85F2265DC3F00929D07 /* VerifiableAccountTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4365E85E2265DC3F00929D07 /* VerifiableAccountTest.swift */; };
    4.40 -		4365E86A226615F200929D07 /* VerifiableAccountIMAP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4365E869226615F200929D07 /* VerifiableAccountIMAP.swift */; };
    4.41 -		4365E87222661B9700929D07 /* VerifiableAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4365E87122661B9700929D07 /* VerifiableAccount.swift */; };
    4.42  		436795F81EE98B9A00B03E23 /* MessageReevalutionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436795F71EE98B9A00B03E23 /* MessageReevalutionTests.swift */; };
    4.43  		436795FB1EE98E9900B03E23 /* CommunicationTypeTests_test002@peptest.ch_sec.asc in Resources */ = {isa = PBXBuildFile; fileRef = 436795F91EE98E9900B03E23 /* CommunicationTypeTests_test002@peptest.ch_sec.asc */; };
    4.44  		436795FC1EE98E9900B03E23 /* CommunicationTypeTests_test002@peptest.ch.asc in Resources */ = {isa = PBXBuildFile; fileRef = 436795FA1EE98E9900B03E23 /* CommunicationTypeTests_test002@peptest.ch.asc */; };
    4.45  		436795FF1EE98F6E00B03E23 /* CommunicationTypeTests_test001@peptest.ch_sec.asc in Resources */ = {isa = PBXBuildFile; fileRef = 436795FD1EE98F6E00B03E23 /* CommunicationTypeTests_test001@peptest.ch_sec.asc */; };
    4.46  		436796001EE98F6E00B03E23 /* CommunicationTypeTests_test001@peptest.ch.asc in Resources */ = {isa = PBXBuildFile; fileRef = 436795FE1EE98F6E00B03E23 /* CommunicationTypeTests_test001@peptest.ch.asc */; };
    4.47  		436796021EE9909100B03E23 /* CommunicationTypeTests_Message_test001_to_test002.txt in Resources */ = {isa = PBXBuildFile; fileRef = 436796011EE9909100B03E23 /* CommunicationTypeTests_Message_test001_to_test002.txt */; };
    4.48 +		436981AD2282F6460006FA2D /* secret.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 436981AC2282F6460006FA2D /* secret.xcconfig */; };
    4.49 +		436981C022830AF60006FA2D /* SecretTestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436981BF22830AF60006FA2D /* SecretTestData.swift */; };
    4.50  		436D0066215B5F3800966CC2 /* Undisplayable_HTML_Message.txt in Resources */ = {isa = PBXBuildFile; fileRef = 436D0065215B5F3800966CC2 /* Undisplayable_HTML_Message.txt */; };
    4.51  		436F8E141D36706A007E9829 /* StringExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436F8E131D36706A007E9829 /* StringExtensionsTest.swift */; };
    4.52  		437027A122315B5700A77AEC /* PEPAppUtilWrappers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437027A022315B5700A77AEC /* PEPAppUtilWrappers.swift */; };
    4.53 @@ -363,9 +360,6 @@
    4.54  		43D47AC0225DD1C500E97C5B /* PantomimeFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D47ABF225DD1C500E97C5B /* PantomimeFramework.framework */; };
    4.55  		43D47AC2225DD1CE00E97C5B /* PEPObjCAdapterFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D47AC1225DD1CE00E97C5B /* PEPObjCAdapterFramework.framework */; };
    4.56  		43D51E891DD5D902008B77A8 /* SimpleOperationsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D51E881DD5D902008B77A8 /* SimpleOperationsTest.swift */; };
    4.57 -		43D541022267029400E74427 /* BasicConnectInfo+VerifiableAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D541012267029400E74427 /* BasicConnectInfo+VerifiableAccount.swift */; };
    4.58 -		43D54107226721A000E74427 /* VerifiableAccountSMTP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D54106226721A000E74427 /* VerifiableAccountSMTP.swift */; };
    4.59 -		43D5411B2268853A00E74427 /* VerifiableAccountProtocol+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D5411A2268853A00E74427 /* VerifiableAccountProtocol+UI.swift */; };
    4.60  		43DA52681CEF1B4F0023D540 /* NewAccountSetupUITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DA52671CEF1B4F0023D540 /* NewAccountSetupUITest.swift */; };
    4.61  		43DFB0331E36083D00175C9C /* MessageHeapBufferOverflow.txt in Resources */ = {isa = PBXBuildFile; fileRef = 43DFB0321E36083D00175C9C /* MessageHeapBufferOverflow.txt */; };
    4.62  		43E1619120D7B2D6003F1514 /* UpdateThreadListDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E1619020D7B2D6003F1514 /* UpdateThreadListDelegate.swift */; };
    4.63 @@ -429,11 +423,9 @@
    4.64  		B722EC651E5B49BA00A2B9D5 /* FolderSectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B722EC641E5B49BA00A2B9D5 /* FolderSectionViewModel.swift */; };
    4.65  		B722EC7A1E5C879000A2B9D5 /* FolderUiProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = B722EC791E5C879000A2B9D5 /* FolderUiProtocols.swift */; };
    4.66  		B729BEC61E7C35E200793110 /* FilterUpdateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B729BEC51E7C35E200793110 /* FilterUpdateProtocol.swift */; };
    4.67 -		B740B75D1E4B1C2D002585E1 /* jsonMimeType.txt in Resources */ = {isa = PBXBuildFile; fileRef = B740B75C1E4B1C2D002585E1 /* jsonMimeType.txt */; };
    4.68  		B74F81021EB0E20000519FCC /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B74F81011EB0E20000519FCC /* LoginViewModel.swift */; };
    4.69  		B75FF00B1EFD420F00C57289 /* EmailListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B75FF00A1EFD420F00C57289 /* EmailListViewModel.swift */; };
    4.70  		B76CF8B320D2739B002429A8 /* MoveToFolderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B76CF8B220D2739B002429A8 /* MoveToFolderViewModel.swift */; };
    4.71 -		B7745839221C191600664282 /* SecretUITestData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7745838221C191600664282 /* SecretUITestData.swift */; };
    4.72  		B78309C81EAA09040051A2E0 /* AccountCreation.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B78309C61EAA09040051A2E0 /* AccountCreation.storyboard */; };
    4.73  		B78CF8251E76D706008C1739 /* FilterTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B78CF8241E76D706008C1739 /* FilterTableViewController.swift */; };
    4.74  		B78CF8291E76E0F1008C1739 /* FilterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B78CF8281E76E0F1008C1739 /* FilterViewModel.swift */; };
    4.75 @@ -511,7 +503,6 @@
    4.76  		0033C08220D7F41600224E61 /* ThreadedEmailViewModelDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadedEmailViewModelDelegate.swift; sourceTree = "<group>"; };
    4.77  		0038494920D25576008000EA /* ProfilePictureComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePictureComposer.swift; sourceTree = "<group>"; };
    4.78  		0038494B20D2587F008000EA /* PepPictureComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PepPictureComposer.swift; sourceTree = "<group>"; };
    4.79 -		003C0FA620B5581A0093A987 /* SecretTestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretTestData.swift; sourceTree = "<group>"; };
    4.80  		004422C72179E3C500BDF6DF /* SettingsCellViewModelTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCellViewModelTest.swift; sourceTree = "<group>"; };
    4.81  		004422C92179ECD600BDF6DF /* PassiveModeViewModelTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassiveModeViewModelTest.swift; sourceTree = "<group>"; };
    4.82  		004422D8217A25AD00BDF6DF /* UnencryptedSubjectViewModelTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnencryptedSubjectViewModelTest.swift; sourceTree = "<group>"; };
    4.83 @@ -604,7 +595,6 @@
    4.84  		15410D242199ECD700BBF65F /* AttachmentViewModelTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentViewModelTest.swift; sourceTree = "<group>"; };
    4.85  		1541D7EC1FC81D4200D52A5D /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = "<group>"; };
    4.86  		1541D7EF1FC81ED900D52A5D /* URL+ExtensionsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+ExtensionsTest.swift"; sourceTree = "<group>"; };
    4.87 -		1541D7F21FC8292D00D52A5D /* URL+MIME.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+MIME.swift"; sourceTree = "<group>"; };
    4.88  		1541D7F41FC82A4900D52A5D /* URL+MIME.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+MIME.swift"; sourceTree = "<group>"; };
    4.89  		1544BD0121524C9F0075C5A0 /* AttachmentFilterTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AttachmentFilterTest.swift; path = pEpForiOSTests/Models/Filter/AttachmentFilterTest.swift; sourceTree = SOURCE_ROOT; };
    4.90  		154D92CE20AC1744009A5868 /* MoveToFolderOperationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveToFolderOperationTest.swift; sourceTree = "<group>"; };
    4.91 @@ -689,6 +679,7 @@
    4.92  		430E0BE61EAF5E2600378EC2 /* NSMutableDictionary+pEp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSMutableDictionary+pEp.swift"; sourceTree = "<group>"; };
    4.93  		430E5F1F1EBC87A700E5D5D3 /* LanguageListTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageListTableViewCell.swift; sourceTree = "<group>"; };
    4.94  		43106A182045716000693144 /* OAuth2ConfigurationProtocol+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OAuth2ConfigurationProtocol+Extension.swift"; sourceTree = "<group>"; };
    4.95 +		4312BE88228439670002129D /* SecretUITestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SecretUITestData.swift; path = ../../pEp_for_iOS_intern/SecretUITestData.swift; sourceTree = "<group>"; };
    4.96  		431394A81E4B03AA00D92F33 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
    4.97  		4315E4C2201242BB00F68763 /* OAuth2Type+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OAuth2Type+Extension.swift"; sourceTree = "<group>"; };
    4.98  		431798761CF87FE6007DD655 /* ReferenceCounter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReferenceCounter.swift; sourceTree = "<group>"; };
    4.99 @@ -698,7 +689,6 @@
   4.100  		431C6E031FE7A85200E23BE0 /* OAuth2ConfigurationProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuth2ConfigurationProtocol.swift; sourceTree = "<group>"; };
   4.101  		431D60DA1E93BB2D001266D7 /* AttachmentsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentsView.swift; sourceTree = "<group>"; };
   4.102  		431D60DC1E93D580001266D7 /* MessageAttachmentsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageAttachmentsCell.swift; sourceTree = "<group>"; };
   4.103 -		431E58FB1ED5926B00EFA77F /* AccountVerificationServiceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountVerificationServiceTests.swift; sourceTree = "<group>"; };
   4.104  		431E65621EEAE65200B8BBFC /* HandshakeUITest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HandshakeUITest.swift; sourceTree = "<group>"; };
   4.105  		431E8F7D1CFDCF3A00C33647 /* EmailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmailViewController.swift; sourceTree = "<group>"; };
   4.106  		431F987E1F6FD3E300A1E4D2 /* HandshakePartnerTableViewCellViewModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HandshakePartnerTableViewCellViewModelTests.swift; sourceTree = "<group>"; };
   4.107 @@ -782,15 +772,14 @@
   4.108  		4356FFEB21356CB600804089 /* ReplyAllPossibleCheckerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplyAllPossibleCheckerTest.swift; sourceTree = "<group>"; };
   4.109  		435F7C74215E05DA00F21EFD /* 1364_Mail_missing_attached_image.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = 1364_Mail_missing_attached_image.txt; sourceTree = "<group>"; };
   4.110  		43628765213D7A5E0066CD03 /* IOS-1300_odt_attachment.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "IOS-1300_odt_attachment.txt"; sourceTree = "<group>"; };
   4.111 -		4365E85E2265DC3F00929D07 /* VerifiableAccountTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifiableAccountTest.swift; sourceTree = "<group>"; };
   4.112 -		4365E869226615F200929D07 /* VerifiableAccountIMAP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifiableAccountIMAP.swift; sourceTree = "<group>"; };
   4.113 -		4365E87122661B9700929D07 /* VerifiableAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifiableAccount.swift; sourceTree = "<group>"; };
   4.114  		436795F71EE98B9A00B03E23 /* MessageReevalutionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageReevalutionTests.swift; sourceTree = "<group>"; };
   4.115  		436795F91EE98E9900B03E23 /* CommunicationTypeTests_test002@peptest.ch_sec.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CommunicationTypeTests_test002@peptest.ch_sec.asc"; sourceTree = "<group>"; };
   4.116  		436795FA1EE98E9900B03E23 /* CommunicationTypeTests_test002@peptest.ch.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CommunicationTypeTests_test002@peptest.ch.asc"; sourceTree = "<group>"; };
   4.117  		436795FD1EE98F6E00B03E23 /* CommunicationTypeTests_test001@peptest.ch_sec.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CommunicationTypeTests_test001@peptest.ch_sec.asc"; sourceTree = "<group>"; };
   4.118  		436795FE1EE98F6E00B03E23 /* CommunicationTypeTests_test001@peptest.ch.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "CommunicationTypeTests_test001@peptest.ch.asc"; sourceTree = "<group>"; };
   4.119  		436796011EE9909100B03E23 /* CommunicationTypeTests_Message_test001_to_test002.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CommunicationTypeTests_Message_test001_to_test002.txt; sourceTree = "<group>"; };
   4.120 +		436981AC2282F6460006FA2D /* secret.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = secret.xcconfig; path = ../../pEp_for_iOS_intern/secret.xcconfig; sourceTree = "<group>"; };
   4.121 +		436981BF22830AF60006FA2D /* SecretTestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SecretTestData.swift; path = ../../../pEp_for_iOS_intern/SecretTestData.swift; sourceTree = "<group>"; };
   4.122  		436C5A8D1CFEDF59006A195F /* UIHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIHelper.swift; sourceTree = "<group>"; };
   4.123  		436D0065215B5F3800966CC2 /* Undisplayable_HTML_Message.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Undisplayable_HTML_Message.txt; sourceTree = "<group>"; };
   4.124  		436F8E131D36706A007E9829 /* StringExtensionsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringExtensionsTest.swift; sourceTree = "<group>"; };
   4.125 @@ -847,7 +836,6 @@
   4.126  		43AE48E61EEFC93900B92BB6 /* DebugMergePolicy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugMergePolicy.swift; sourceTree = "<group>"; };
   4.127  		43B0443820067CC7007BCE3F /* UIAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAccount.swift; sourceTree = "<group>"; };
   4.128  		43B0443A20067D25007BCE3F /* UITestDataProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestDataProtocol.swift; sourceTree = "<group>"; };
   4.129 -		43B044412007683E007BCE3F /* secret.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = secret.xcconfig; sourceTree = "<group>"; };
   4.130  		43B0444B20077323007BCE3F /* OAuth2Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuth2Configuration.swift; sourceTree = "<group>"; };
   4.131  		43B10C7F1EC2EE7F003E849F /* CppDummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CppDummy.cpp; sourceTree = "<group>"; };
   4.132  		43B2C3161D2280ED00A08557 /* 5A90_3590_0E48_AB85_F3DB__045E_4623_C5D1_EAB6_643E.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = 5A90_3590_0E48_AB85_F3DB__045E_4623_C5D1_EAB6_643E.asc; sourceTree = "<group>"; };
   4.133 @@ -883,9 +871,6 @@
   4.134  		43D47ABF225DD1C500E97C5B /* PantomimeFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PantomimeFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
   4.135  		43D47AC1225DD1CE00E97C5B /* PEPObjCAdapterFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PEPObjCAdapterFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
   4.136  		43D51E881DD5D902008B77A8 /* SimpleOperationsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimpleOperationsTest.swift; sourceTree = "<group>"; };
   4.137 -		43D541012267029400E74427 /* BasicConnectInfo+VerifiableAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BasicConnectInfo+VerifiableAccount.swift"; sourceTree = "<group>"; };
   4.138 -		43D54106226721A000E74427 /* VerifiableAccountSMTP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifiableAccountSMTP.swift; sourceTree = "<group>"; };
   4.139 -		43D5411A2268853A00E74427 /* VerifiableAccountProtocol+UI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VerifiableAccountProtocol+UI.swift"; sourceTree = "<group>"; };
   4.140  		43DA52671CEF1B4F0023D540 /* NewAccountSetupUITest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewAccountSetupUITest.swift; sourceTree = "<group>"; };
   4.141  		43DFB0321E36083D00175C9C /* MessageHeapBufferOverflow.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MessageHeapBufferOverflow.txt; sourceTree = "<group>"; };
   4.142  		43E1619020D7B2D6003F1514 /* UpdateThreadListDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateThreadListDelegate.swift; sourceTree = "<group>"; };
   4.143 @@ -950,11 +935,9 @@
   4.144  		B722EC641E5B49BA00A2B9D5 /* FolderSectionViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FolderSectionViewModel.swift; path = Folder/ViewModel/FolderSectionViewModel.swift; sourceTree = "<group>"; };
   4.145  		B722EC791E5C879000A2B9D5 /* FolderUiProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolderUiProtocols.swift; sourceTree = "<group>"; };
   4.146  		B729BEC51E7C35E200793110 /* FilterUpdateProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FilterUpdateProtocol.swift; path = Filter/ViewModel/FilterUpdateProtocol.swift; sourceTree = "<group>"; };
   4.147 -		B740B75C1E4B1C2D002585E1 /* jsonMimeType.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = jsonMimeType.txt; sourceTree = "<group>"; };
   4.148  		B74F81011EB0E20000519FCC /* LoginViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = "<group>"; };
   4.149  		B75FF00A1EFD420F00C57289 /* EmailListViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmailListViewModel.swift; sourceTree = "<group>"; };
   4.150  		B76CF8B220D2739B002429A8 /* MoveToFolderViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveToFolderViewModel.swift; sourceTree = "<group>"; };
   4.151 -		B7745838221C191600664282 /* SecretUITestData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecretUITestData.swift; sourceTree = "<group>"; };
   4.152  		B78309C71EAA09040051A2E0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/AccountCreation.storyboard; sourceTree = "<group>"; };
   4.153  		B78CF8241E76D706008C1739 /* FilterTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FilterTableViewController.swift; path = Filter/FilterTableViewController.swift; sourceTree = "<group>"; };
   4.154  		B78CF8281E76E0F1008C1739 /* FilterViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FilterViewModel.swift; path = Filter/ViewModel/FilterViewModel.swift; sourceTree = "<group>"; };
   4.155 @@ -1078,13 +1061,13 @@
   4.156  		151F71EB202A06750057C74D /* TestUtils */ = {
   4.157  			isa = PBXGroup;
   4.158  			children = (
   4.159 +				436981BF22830AF60006FA2D /* SecretTestData.swift */,
   4.160  				151F71F6202A06750057C74D /* CdAccount+TestUtils.swift */,
   4.161  				151F71F3202A06750057C74D /* CdMessage+TestUtils.swift */,
   4.162  				151F71F1202A06750057C74D /* CoreDataDrivenTestBase.swift */,
   4.163  				1555361A207796CE00CDDAFA /* CWInternetAddress+TestUtils.swift */,
   4.164  				151F71EF202A06750057C74D /* DecryptionAttemptCounterDelegate.swift */,
   4.165  				151F71F4202A06750057C74D /* Message+TestUtils.swift */,
   4.166 -				003C0FA620B5581A0093A987 /* SecretTestData.swift */,
   4.167  				151F71F0202A06750057C74D /* MockBackgrounder.swift */,
   4.168  				151F71EE202A06750057C74D /* ReplicationServiceObserver.swift */,
   4.169  				151F71EC202A06750057C74D /* TestDataBase.swift */,
   4.170 @@ -1732,7 +1715,6 @@
   4.171  				431C2B181F38888B00D87FFD /* ConnectionTransport+AccountSettings.swift */,
   4.172  				43257C871F5067BE00DDC7F0 /* NSAttributedString+pEp.swift */,
   4.173  				1541D7EC1FC81D4200D52A5D /* URL+Extensions.swift */,
   4.174 -				1541D7F21FC8292D00D52A5D /* URL+MIME.swift */,
   4.175  				155050F11FE95D8A009CEAD2 /* UserNotificationTool+pEp.swift */,
   4.176  				439A23E420B40FAC00417AF5 /* PEP_rating+Extension.swift */,
   4.177  				1574D079211464CC00FEDC93 /* URL+MailTo.swift */,
   4.178 @@ -1740,18 +1722,6 @@
   4.179  			path = Extensions;
   4.180  			sourceTree = "<group>";
   4.181  		};
   4.182 -		4365E868226615E400929D07 /* VerifiableAccount */ = {
   4.183 -			isa = PBXGroup;
   4.184 -			children = (
   4.185 -				4365E87122661B9700929D07 /* VerifiableAccount.swift */,
   4.186 -				4365E869226615F200929D07 /* VerifiableAccountIMAP.swift */,
   4.187 -				43D54106226721A000E74427 /* VerifiableAccountSMTP.swift */,
   4.188 -				43D541012267029400E74427 /* BasicConnectInfo+VerifiableAccount.swift */,
   4.189 -				43D5411A2268853A00E74427 /* VerifiableAccountProtocol+UI.swift */,
   4.190 -			);
   4.191 -			path = VerifiableAccount;
   4.192 -			sourceTree = "<group>";
   4.193 -		};
   4.194  		43800D8C1D112A0800821E34 /* HTMLParser */ = {
   4.195  			isa = PBXGroup;
   4.196  			children = (
   4.197 @@ -1818,8 +1788,8 @@
   4.198  				43980E351CBD0BCA00A7FC3C /* Info.plist */,
   4.199  				43C98AC5219C3691006418B0 /* InfoPlist.strings */,
   4.200  				43C98AC1219C275E006418B0 /* Localizable.strings */,
   4.201 +				436981AC2282F6460006FA2D /* secret.xcconfig */,
   4.202  				4388A0E02008AF61008CB98D /* public.xcconfig */,
   4.203 -				43B044412007683E007BCE3F /* secret.xcconfig */,
   4.204  				433724FC1DA2C2B1005E8DF5 /* pEp.entitlements */,
   4.205  				430C80D41D0EAB6E00CD4582 /* pEpTrustWords.bundle */,
   4.206  			);
   4.207 @@ -1840,7 +1810,6 @@
   4.208  				150707DD21006D0200AA213F /* UI */,
   4.209  				151F7202202A06D30057C74D /* Util */,
   4.210  				15F82A072006552B0084F9EA /* Tests from MessageModel in Exile due to Apple Bug */,
   4.211 -				43A601252264B5050099B45C /* Service */,
   4.212  				43980E401CBD0BCA00A7FC3C /* Info.plist */,
   4.213  				4336229D1DC76B8100133B3D /* MessageModelTests.swift */,
   4.214  				438D253B1D4B9E7500BFF7AA /* MimeTests.swift */,
   4.215 @@ -1857,7 +1826,6 @@
   4.216  				438281821E891B7E00087343 /* DateTests.swift */,
   4.217  				43FAA0D31EC9CBC0005BFC4B /* DecryptionTestsInternal.swift */,
   4.218  				43C3B15F2003851100ED48A4 /* DecryptImportedMessagesTests.swift */,
   4.219 -				431E58FB1ED5926B00EFA77F /* AccountVerificationServiceTests.swift */,
   4.220  				436795F71EE98B9A00B03E23 /* MessageReevalutionTests.swift */,
   4.221  				15B483DA1F28E2FC000FB2CF /* SpecialUseMailboxesTest.swift */,
   4.222  				43F7F0791F6AD44600BDF151 /* HandshakeTests.swift */,
   4.223 @@ -1877,7 +1845,7 @@
   4.224  		43980E481CBD0BCA00A7FC3C /* pEpForiOSUITests */ = {
   4.225  			isa = PBXGroup;
   4.226  			children = (
   4.227 -				B7745838221C191600664282 /* SecretUITestData.swift */,
   4.228 +				4312BE88228439670002129D /* SecretUITestData.swift */,
   4.229  				43B0443A20067D25007BCE3F /* UITestDataProtocol.swift */,
   4.230  				43B0443820067CC7007BCE3F /* UIAccount.swift */,
   4.231  				43980E4B1CBD0BCA00A7FC3C /* Info.plist */,
   4.232 @@ -1902,7 +1870,6 @@
   4.233  			isa = PBXGroup;
   4.234  			children = (
   4.235  				4362398D1EAE08F400BD2EB9 /* Extensions */,
   4.236 -				B740B7571E4B1B80002585E1 /* MimeTypes */,
   4.237  				43306EBC1FE125950045DD00 /* OAuth2 */,
   4.238  				43980EF91CBD415700A7FC3C /* AppConfig.swift */,
   4.239  				A1B50A811CD26FF100B1A997 /* Constants.swift */,
   4.240 @@ -1933,14 +1900,6 @@
   4.241  			name = Raw;
   4.242  			sourceTree = "<group>";
   4.243  		};
   4.244 -		43A601252264B5050099B45C /* Service */ = {
   4.245 -			isa = PBXGroup;
   4.246 -			children = (
   4.247 -				4365E85E2265DC3F00929D07 /* VerifiableAccountTest.swift */,
   4.248 -			);
   4.249 -			path = Service;
   4.250 -			sourceTree = "<group>";
   4.251 -		};
   4.252  		43A6E0491E5726C8005BEE69 /* Background */ = {
   4.253  			isa = PBXGroup;
   4.254  			children = (
   4.255 @@ -2041,8 +2000,6 @@
   4.256  			isa = PBXGroup;
   4.257  			children = (
   4.258  				37C3C0E52260C64D003E290C /* Log.swift */,
   4.259 -				15F835231F34BE1300FCE887 /* AccountUserInput.swift */,
   4.260 -				4365E868226615E400929D07 /* VerifiableAccount */,
   4.261  				43CE63C41DE87FB200FAC505 /* Identity+pEp.swift */,
   4.262  				155475632137FD96005A52D0 /* FolderType+Extensions.swift */,
   4.263  				1554756521393036005A52D0 /* Folder+Extensions.swift */,
   4.264 @@ -2394,14 +2351,6 @@
   4.265  			name = CellsAndSections;
   4.266  			sourceTree = "<group>";
   4.267  		};
   4.268 -		B740B7571E4B1B80002585E1 /* MimeTypes */ = {
   4.269 -			isa = PBXGroup;
   4.270 -			children = (
   4.271 -				B740B75C1E4B1C2D002585E1 /* jsonMimeType.txt */,
   4.272 -			);
   4.273 -			name = MimeTypes;
   4.274 -			sourceTree = "<group>";
   4.275 -		};
   4.276  		B74D08BF1F013F15003D092C /* ViewModel */ = {
   4.277  			isa = PBXGroup;
   4.278  			children = (
   4.279 @@ -2603,10 +2552,10 @@
   4.280  				1526596C216230B1006A78DF /* ComposeData.plist in Resources */,
   4.281  				43980E341CBD0BCA00A7FC3C /* LaunchScreen.storyboard in Resources */,
   4.282  				155F2D9E20530798001B4B1C /* Reusable.storyboard in Resources */,
   4.283 +				436981AD2282F6460006FA2D /* secret.xcconfig in Resources */,
   4.284  				220DCE2F1E0AB544002FE716 /* MessageData.plist in Resources */,
   4.285  				432E80FE2191AF5100359879 /* UniversLTStd-Bold.otf in Resources */,
   4.286  				43980E311CBD0BCA00A7FC3C /* Assets.xcassets in Resources */,
   4.287 -				B740B75D1E4B1C2D002585E1 /* jsonMimeType.txt in Resources */,
   4.288  				151DE7E41FC5D41600CDC273 /* FolderViews.storyboard in Resources */,
   4.289  				152A39D221905C3E00D9F8E4 /* AttachmentCell.xib in Resources */,
   4.290  				43C98AC7219C3691006418B0 /* InfoPlist.strings in Resources */,
   4.291 @@ -2755,8 +2704,6 @@
   4.292  			files = (
   4.293  				002375D420DCF59D00663961 /* MoveToAccountViewController.swift in Sources */,
   4.294  				496C0EEB20BC4B370009B5B9 /* EmailListViewModel+EmailDisplayDelegate.swift in Sources */,
   4.295 -				B70A3A9422089D5000EDCE61 /* Log.swift in Sources */,
   4.296 -				4365E86A226615F200929D07 /* VerifiableAccountIMAP.swift in Sources */,
   4.297  				4315E4C3201242BB00F68763 /* OAuth2Type+Extension.swift in Sources */,
   4.298  				4351C2D11F4441190053381F /* houdini_html_u.c in Sources */,
   4.299  				B70A3C401E817CFA0036876F /* FolderViewModel.swift in Sources */,
   4.300 @@ -2793,7 +2740,6 @@
   4.301  				006BE6BC20F4B63C00DDE8C9 /* EmailDetailType.swift in Sources */,
   4.302  				00EB89AB20E3A27C00CDFA0D /* ThreadViewcontroller+SizeClasses.swift in Sources */,
   4.303  				43257C841F50629700DDC7F0 /* HtmlToAttributedTextSaxParser.swift in Sources */,
   4.304 -				1541D7F31FC8292D00D52A5D /* URL+MIME.swift in Sources */,
   4.305  				4351C2D61F4441190053381F /* man.c in Sources */,
   4.306  				150B8EB31FCEB93D00374438 /* UIUtils.swift in Sources */,
   4.307  				43AAC22A1F7A5AEE00F435F4 /* BaseTableViewController.swift in Sources */,
   4.308 @@ -2817,7 +2763,6 @@
   4.309  				152A39D621905C3E00D9F8E4 /* BodyCell.swift in Sources */,
   4.310  				43ED53791CC77F95006AB156 /* UserInfoTableViewController.swift in Sources */,
   4.311  				43EC75AC2164C26100048CFE /* SetOwnKeyViewController.swift in Sources */,
   4.312 -				4365E87222661B9700929D07 /* VerifiableAccount.swift in Sources */,
   4.313  				43CE63C51DE87FB200FAC505 /* Identity+pEp.swift in Sources */,
   4.314  				220DCE2E1E0AB544002FE716 /* MessageCell.swift in Sources */,
   4.315  				B7DB7FD8221AD3BB003968DA /* UITableView+Extension.swift in Sources */,
   4.316 @@ -2893,7 +2838,6 @@
   4.317  				B7DB7FCA2215D69C003968DA /* CredentialTextField.swift in Sources */,
   4.318  				433E7438225B564400B84CD9 /* Account+Extension.swift in Sources */,
   4.319  				005A21FB20CAA5F50082D19F /* ThreadedEmailViewModel.swift in Sources */,
   4.320 -				43D541022267029400E74427 /* BasicConnectInfo+VerifiableAccount.swift in Sources */,
   4.321  				15874BD12127493E00A3A4A6 /* TrustedServerSettingsViewModel.swift in Sources */,
   4.322  				4351C2DC1F4441190053381F /* xml.c in Sources */,
   4.323  				430E0BE71EAF5E2600378EC2 /* NSMutableDictionary+pEp.swift in Sources */,
   4.324 @@ -2927,7 +2871,6 @@
   4.325  				152A39E321905C3E00D9F8E4 /* RecipientTextView.swift in Sources */,
   4.326  				43ED53701CC77F95006AB156 /* EmailListViewController.swift in Sources */,
   4.327  				496C0EE720BC2A880009B5B9 /* EmailDisplayDelegate.swift in Sources */,
   4.328 -				43D5411B2268853A00E74427 /* VerifiableAccountProtocol+UI.swift in Sources */,
   4.329  				152A39DD21905C3E00D9F8E4 /* AccountCell.swift in Sources */,
   4.330  				B7DB7FDC221ADDBD003968DA /* UIImageView+Extension.swift in Sources */,
   4.331  				37C3C0E62260C64D003E290C /* Log.swift in Sources */,
   4.332 @@ -3014,7 +2957,6 @@
   4.333  				15874BCF2127493E00A3A4A6 /* AccountSettingsTableViewController.swift in Sources */,
   4.334  				B7DB7FC72215C57F003968DA /* UIView+Autolayout.swift in Sources */,
   4.335  				B71EBBBC1E55E4AE00150177 /* FolderTableViewController.swift in Sources */,
   4.336 -				43D54107226721A000E74427 /* VerifiableAccountSMTP.swift in Sources */,
   4.337  				492EF92F20C699D0004EAE14 /* ThreadViewController+TableView.swift in Sources */,
   4.338  				43D070312133DB920013B120 /* AppSettingsProtocol.swift in Sources */,
   4.339  				43ED53781CC77F95006AB156 /* SMTPSettingsTableViewController.swift in Sources */,
   4.340 @@ -3028,7 +2970,6 @@
   4.341  			files = (
   4.342  				438D253C1D4B9E7500BFF7AA /* MimeTests.swift in Sources */,
   4.343  				004422CA2179ECD600BDF6DF /* PassiveModeViewModelTest.swift in Sources */,
   4.344 -				003C0FA720B5581A0093A987 /* SecretTestData.swift in Sources */,
   4.345  				1555361B207796CE00CDDAFA /* CWInternetAddress+TestUtils.swift in Sources */,
   4.346  				154D92CF20AC1745009A5868 /* MoveToFolderOperationTest.swift in Sources */,
   4.347  				1544BD0221524C9F0075C5A0 /* AttachmentFilterTest.swift in Sources */,
   4.348 @@ -3041,7 +2982,6 @@
   4.349  				153B2188219472A400497D3D /* BodyCellViewModelTest.swift in Sources */,
   4.350  				438BA0F5214F89CD001A4A82 /* MailParsingTests.swift in Sources */,
   4.351  				15A8B8FC20908D2300D2B0B6 /* Keychain+TestUtils.swift in Sources */,
   4.352 -				431E58FC1ED5926B00EFA77F /* AccountVerificationServiceTests.swift in Sources */,
   4.353  				0017CD1D2162614400F62F13 /* MoveToFolderCellViewModelTests.swift in Sources */,
   4.354  				0017CD1B21621E2200F62F13 /* MoveToFolderViewModelTest.swift in Sources */,
   4.355  				4336229E1DC76B8100133B3D /* MessageModelTests.swift in Sources */,
   4.356 @@ -3049,6 +2989,7 @@
   4.357  				43FAA0D41EC9CBC0005BFC4B /* DecryptionTestsInternal.swift in Sources */,
   4.358  				F73E4F72217F238300CCFFED /* FolderSectionViewModelTests.swift in Sources */,
   4.359  				15A763D11F72D68000670313 /* KeyChainTest.swift in Sources */,
   4.360 +				436981C022830AF60006FA2D /* SecretTestData.swift in Sources */,
   4.361  				43EC75B32164E97800048CFE /* DecryptionUtil.swift in Sources */,
   4.362  				43C7B9D11CEC4DDF007A612F /* MiscTests.swift in Sources */,
   4.363  				434DDC2B20D10F9A00755F44 /* EncryptionTests.swift in Sources */,
   4.364 @@ -3112,7 +3053,6 @@
   4.365  				15D439A5216F7E0E00EB3933 /* AccountPickerViewModelTest.swift in Sources */,
   4.366  				1574D07D2114696B00FEDC93 /* URL+MailToTest.swift in Sources */,
   4.367  				43C273DD21C9024A002EB4C8 /* LoggerTest.swift in Sources */,
   4.368 -				4365E85F2265DC3F00929D07 /* VerifiableAccountTest.swift in Sources */,
   4.369  				4356FFEC21356CB600804089 /* ReplyAllPossibleCheckerTest.swift in Sources */,
   4.370  				430C80E01D0EADC200CD4582 /* PepAdapterTests.swift in Sources */,
   4.371  				00DF2C3B2164C53F004EBA6C /* FolderViewModelTest.swift in Sources */,
   4.372 @@ -3138,7 +3078,7 @@
   4.373  				434C051B20F8BAB6009B271D /* XCUIElement+Extension.swift in Sources */,
   4.374  				431E65631EEAE65200B8BBFC /* HandshakeUITest.swift in Sources */,
   4.375  				43B0443B20067D25007BCE3F /* UITestDataProtocol.swift in Sources */,
   4.376 -				B7745839221C191600664282 /* SecretUITestData.swift in Sources */,
   4.377 +				4312BE89228439670002129D /* SecretUITestData.swift in Sources */,
   4.378  			);
   4.379  			runOnlyForDeploymentPostprocessing = 0;
   4.380  		};
     5.1 --- a/pEpForiOS/Base.lproj/Settings.storyboard	Wed May 08 12:31:03 2019 +0200
     5.2 +++ b/pEpForiOS/Base.lproj/Settings.storyboard	Fri May 17 14:16:55 2019 +0200
     5.3 @@ -1,11 +1,11 @@
     5.4  <?xml version="1.0" encoding="UTF-8"?>
     5.5 -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="cPx-YX-3ty">
     5.6 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="cPx-YX-3ty">
     5.7      <device id="retina4_7" orientation="portrait">
     5.8          <adaptation id="fullscreen"/>
     5.9      </device>
    5.10      <dependencies>
    5.11          <deployment identifier="iOS"/>
    5.12 -        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
    5.13 +        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
    5.14          <capability name="Safe area layout guides" minToolsVersion="9.0"/>
    5.15          <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    5.16      </dependencies>
    5.17 @@ -651,6 +651,7 @@
    5.18                      <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
    5.19                      <simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
    5.20                      <connections>
    5.21 +                        <outlet property="doneButton" destination="Xy6-Rf-YDv" id="twm-qo-BhD"/>
    5.22                          <outlet property="emailTextfield" destination="FIa-wa-uSF" id="RVW-cY-4Ny"/>
    5.23                          <outlet property="imapPortTextfield" destination="ukB-K0-MMG" id="rGA-tC-CYA"/>
    5.24                          <outlet property="imapSecurityTextfield" destination="rCJ-UW-Jmn" id="Vz4-6T-rdl"/>
     6.1 --- a/pEpForiOS/HTMLParser/Axt/HtmlToAttributedTextSaxParser.swift	Wed May 08 12:31:03 2019 +0200
     6.2 +++ b/pEpForiOS/HTMLParser/Axt/HtmlToAttributedTextSaxParser.swift	Fri May 17 14:16:55 2019 +0200
     6.3 @@ -18,7 +18,6 @@
     6.4  class HtmlToAttributedTextSaxParser: HtmlToTextSaxParser {
     6.5      var attributedOutput = NSMutableAttributedString()
     6.6      let defaultFont = UIFont.preferredFont(forTextStyle: .body)
     6.7 -    let mimeUtil = MimeTypeUtil()
     6.8  
     6.9      weak var attachmentDelegate: HtmlToAttributedTextSaxParserAttachmentDelegate?
    6.10  
     7.1 --- a/pEpForiOS/Models/VerifiableAccount/BasicConnectInfo+VerifiableAccount.swift	Wed May 08 12:31:03 2019 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,49 +0,0 @@
     7.4 -//
     7.5 -//  BasicConnectInfo+VerifiableAccount.swift
     7.6 -//  pEp
     7.7 -//
     7.8 -//  Created by Dirk Zimmermann on 16.04.19.
     7.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    7.10 -//
    7.11 -
    7.12 -import Foundation
    7.13 -
    7.14 -import PantomimeFramework
    7.15 -import MessageModel
    7.16 -
    7.17 -public extension BasicConnectInfo {
    7.18 -    init?(verifiableAccount: VerifiableAccountProtocol, emailProtocol: EmailProtocol) {
    7.19 -        guard let theAddress = verifiableAccount.address else {
    7.20 -            return nil
    7.21 -        }
    7.22 -
    7.23 -        switch emailProtocol {
    7.24 -        case .imap:
    7.25 -            guard let severAddress = verifiableAccount.serverIMAP else {
    7.26 -                return nil
    7.27 -            }
    7.28 -            self.init(accountEmailAddress: theAddress,
    7.29 -                      loginName: verifiableAccount.loginName,
    7.30 -                      loginPassword: verifiableAccount.password,
    7.31 -                      accessToken: verifiableAccount.accessToken,
    7.32 -                      networkAddress: severAddress,
    7.33 -                      networkPort: verifiableAccount.portIMAP,
    7.34 -                      connectionTransport: verifiableAccount.transportIMAP,
    7.35 -                      authMethod: verifiableAccount.authMethod,
    7.36 -                      emailProtocol: emailProtocol)
    7.37 -        case .smtp:
    7.38 -            guard let severAddress = verifiableAccount.serverSMTP else {
    7.39 -                return nil
    7.40 -            }
    7.41 -            self.init(accountEmailAddress: theAddress,
    7.42 -                      loginName: verifiableAccount.loginName,
    7.43 -                      loginPassword: verifiableAccount.password,
    7.44 -                      accessToken: verifiableAccount.accessToken,
    7.45 -                      networkAddress: severAddress,
    7.46 -                      networkPort: verifiableAccount.portSMTP,
    7.47 -                      connectionTransport: verifiableAccount.transportSMTP,
    7.48 -                      authMethod: verifiableAccount.authMethod,
    7.49 -                      emailProtocol: emailProtocol)
    7.50 -        }
    7.51 -    }
    7.52 -}
     8.1 --- a/pEpForiOS/Models/VerifiableAccount/VerifiableAccount.swift	Wed May 08 12:31:03 2019 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,475 +0,0 @@
     8.4 -//
     8.5 -//  VerifiableAccount.swift
     8.6 -//  pEpForiOS
     8.7 -//
     8.8 -//  Created by buff on 04.08.17.
     8.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
    8.10 -//
    8.11 -
    8.12 -import MessageModel
    8.13 -import PantomimeFramework
    8.14 -import CoreData
    8.15 -
    8.16 -public class VerifiableAccount: VerifiableAccountProtocol {
    8.17 -    // MARK: - VerifiableAccountProtocol (data)
    8.18 -
    8.19 -    public weak var verifiableAccountDelegate: VerifiableAccountDelegate?
    8.20 -
    8.21 -    public var address: String?
    8.22 -
    8.23 -    /**
    8.24 -     The actual name of the user, or nick name. Not to be confused with the login name.
    8.25 -     */
    8.26 -    public var userName: String?
    8.27 -
    8.28 -    /**
    8.29 -     An optional name for the servers, if needed.
    8.30 -     */
    8.31 -    public var loginName: String?
    8.32 -
    8.33 -    /**
    8.34 -     Currently, the only use case for this is .saslXoauth2. In all other cases,
    8.35 -     this should be nil.
    8.36 -     */
    8.37 -    public var authMethod: AuthMethod?
    8.38 -
    8.39 -    public var password: String?
    8.40 -
    8.41 -    /**
    8.42 -     If the user chose OAuth2, this is the token. `password` then should be nil.
    8.43 -     */
    8.44 -    public var accessToken: OAuth2AccessTokenProtocol?
    8.45 -
    8.46 -    public var serverIMAP: String?
    8.47 -    public var portIMAP: UInt16 = 993
    8.48 -    public var transportIMAP = ConnectionTransport.TLS
    8.49 -    public var serverSMTP: String?
    8.50 -    public var portSMTP: UInt16 = 587
    8.51 -    public var transportSMTP = ConnectionTransport.startTLS
    8.52 -
    8.53 -    public var trustedImapServer: Bool
    8.54 -
    8.55 -    public init(verifiableAccountDelegate: VerifiableAccountDelegate?,
    8.56 -                address: String?,
    8.57 -                userName: String?,
    8.58 -                loginName: String?,
    8.59 -                authMethod: AuthMethod?,
    8.60 -                password: String?,
    8.61 -                accessToken: OAuth2AccessTokenProtocol?,
    8.62 -                serverIMAP: String?,
    8.63 -                portIMAP: UInt16,
    8.64 -                transportIMAP: ConnectionTransport,
    8.65 -                serverSMTP: String?,
    8.66 -                portSMTP: UInt16,
    8.67 -                transportSMTP: ConnectionTransport,
    8.68 -                trustedImapServer: Bool) {
    8.69 -        self.verifiableAccountDelegate = verifiableAccountDelegate
    8.70 -        self.address = address
    8.71 -        self.userName = userName
    8.72 -        self.loginName = loginName
    8.73 -        self.authMethod = authMethod
    8.74 -        self.password = password
    8.75 -        self.accessToken = accessToken
    8.76 -        self.serverIMAP = serverIMAP
    8.77 -        self .portIMAP = portIMAP
    8.78 -        self.transportIMAP = transportIMAP
    8.79 -        self.serverSMTP = serverSMTP
    8.80 -        self.portSMTP = portSMTP
    8.81 -        self.transportSMTP = transportSMTP
    8.82 -        self.trustedImapServer = trustedImapServer
    8.83 -    }
    8.84 -
    8.85 -    public convenience init() {
    8.86 -        self.init(verifiableAccountDelegate: nil,
    8.87 -                  address: nil,
    8.88 -                  userName: nil,
    8.89 -                  loginName: nil,
    8.90 -                  authMethod: nil,
    8.91 -                  password: nil,
    8.92 -                  accessToken: nil,
    8.93 -                  serverIMAP: nil,
    8.94 -                  portIMAP: 993,
    8.95 -                  transportIMAP: ConnectionTransport.TLS,
    8.96 -                  serverSMTP: nil,
    8.97 -                  portSMTP: 587,
    8.98 -                  transportSMTP: ConnectionTransport.startTLS,
    8.99 -                  trustedImapServer: false)
   8.100 -    }
   8.101 -
   8.102 -    // MARK: - Internal
   8.103 -
   8.104 -    private var imapVerifier: VerifiableAccountIMAP?
   8.105 -    private var smtpVerifier: VerifiableAccountSMTP?
   8.106 -
   8.107 -    var imapResult: Result<Void, Error>? = nil
   8.108 -    var smtpResult: Result<Void, Error>? = nil
   8.109 -
   8.110 -    /// Used for synchronizing the 2 asynchronous results (IMAP and SMTP verification).
   8.111 -    private let syncQueue = DispatchQueue(label: "VerifiableAccountSynchronization")
   8.112 -
   8.113 -    // MARK: - VerifiableAccountProtocol (behavior)
   8.114 -
   8.115 -    private func isValid() -> Bool {
   8.116 -        let isValid =
   8.117 -            (address?.count ?? 0) > 0 &&
   8.118 -                ((authMethod == .saslXoauth2 && accessToken != nil && password == nil) ||
   8.119 -                    (accessToken == nil && password != nil)) &&
   8.120 -                portIMAP > 0 &&
   8.121 -                portSMTP > 0 &&
   8.122 -                (serverIMAP?.count ?? 0) > 0 &&
   8.123 -                (serverSMTP?.count ?? 0) > 0
   8.124 -        return isValid
   8.125 -    }
   8.126 -
   8.127 -    private func startImapVerification() throws {
   8.128 -        let theVerifier = VerifiableAccountIMAP()
   8.129 -        self.imapVerifier = theVerifier
   8.130 -        theVerifier.verifiableAccountDelegate = self
   8.131 -        guard let imapConnectInfo = BasicConnectInfo(
   8.132 -            verifiableAccount: self, emailProtocol: .imap) else {
   8.133 -                // Assuming this is caused by invalid data.
   8.134 -                throw VerifiableAccountError.invalidUserData
   8.135 -        }
   8.136 -        theVerifier.verify(basicConnectInfo: imapConnectInfo)
   8.137 -    }
   8.138 -
   8.139 -    private func startSmtpVerification() throws {
   8.140 -        let theVerifier = VerifiableAccountSMTP()
   8.141 -        self.smtpVerifier = theVerifier
   8.142 -        theVerifier.verifiableAccountDelegate = self
   8.143 -        guard let smtpConnectInfo = BasicConnectInfo(
   8.144 -            verifiableAccount: self, emailProtocol: .smtp) else {
   8.145 -                // Assuming this is caused by invalid data.
   8.146 -                throw VerifiableAccountError.invalidUserData
   8.147 -        }
   8.148 -        theVerifier.verify(basicConnectInfo: smtpConnectInfo)
   8.149 -    }
   8.150 -
   8.151 -    public func verify() throws {
   8.152 -        if !isValid() {
   8.153 -            throw VerifiableAccountError.invalidUserData
   8.154 -        }
   8.155 -
   8.156 -        try startImapVerification()
   8.157 -        try startSmtpVerification()
   8.158 -    }
   8.159 -
   8.160 -    public func save() throws {
   8.161 -        if !isValid() {
   8.162 -            throw VerifiableAccountError.invalidUserData
   8.163 -        }
   8.164 -
   8.165 -        guard let addressImap = serverIMAP else {
   8.166 -            throw VerifiableAccountError.invalidUserData
   8.167 -        }
   8.168 -
   8.169 -        guard let addressSmtp = serverSMTP else {
   8.170 -            throw VerifiableAccountError.invalidUserData
   8.171 -        }
   8.172 -
   8.173 -        let moc = Record.Context.background
   8.174 -
   8.175 -        moc.performAndWait {
   8.176 -            let cdIdentity = updateOrCreateOwnIdentity(context: moc,
   8.177 -                                                       address: address,
   8.178 -                                                       userName: userName)
   8.179 -
   8.180 -            let cdAccount = findOrCreateAccount(context: moc, identity: cdIdentity)
   8.181 -
   8.182 -            // TODO: Reuse server!
   8.183 -            if let theServer = cdAccount.imapCdServer {
   8.184 -                delete(server: theServer, fromAccount: cdAccount)
   8.185 -            }
   8.186 -
   8.187 -            // TODO: Reuse server!
   8.188 -            if let theServer = cdAccount.smtpCdServer {
   8.189 -                delete(server: theServer, fromAccount: cdAccount)
   8.190 -            }
   8.191 -
   8.192 -            let imapServer = createServer(context: moc,
   8.193 -                                          address: addressImap,
   8.194 -                                          port: portIMAP,
   8.195 -                                          serverType: .imap,
   8.196 -                                          authMethod: authMethod,
   8.197 -                                          trusted: trustedImapServer,
   8.198 -                                          transport: transportIMAP)
   8.199 -
   8.200 -            let smtpServer = createServer(context: moc,
   8.201 -                                          address: addressSmtp,
   8.202 -                                          port: portSMTP,
   8.203 -                                          serverType: .smtp,
   8.204 -                                          authMethod: authMethod,
   8.205 -                                          trusted: false,
   8.206 -                                          transport: transportSMTP)
   8.207 -
   8.208 -            let credentialsImap = createCredentials(context: moc,
   8.209 -                                                    loginName: loginName,
   8.210 -                                                    address: address,
   8.211 -                                                    password: password,
   8.212 -                                                    accessToken: accessToken)
   8.213 -            credentialsImap.servers = NSSet(array: [imapServer])
   8.214 -            imapServer.credentials = credentialsImap
   8.215 -
   8.216 -            let credentialsSmtp = createCredentials(context: moc,
   8.217 -                                                    loginName: loginName,
   8.218 -                                                    address: address,
   8.219 -                                                    password: password,
   8.220 -                                                    accessToken: accessToken)
   8.221 -            credentialsSmtp.servers = NSSet(array: [smtpServer])
   8.222 -            smtpServer.credentials = credentialsSmtp
   8.223 -
   8.224 -            cdAccount.servers = NSSet(array: [imapServer, smtpServer])
   8.225 -
   8.226 -            moc.saveAndLogErrors()
   8.227 -        }
   8.228 -    }
   8.229 -
   8.230 -    // MARK: - Used by the UI, when using class directly
   8.231 -
   8.232 -    public var isValidName: Bool {
   8.233 -        return (userName?.count ?? 0) >= 1
   8.234 -    }
   8.235 -
   8.236 -    public var isValidUser: Bool {
   8.237 -        return isValidName && isValidEmail && isValidPassword
   8.238 -    }
   8.239 -
   8.240 -    private var isValidEmail: Bool {
   8.241 -        return address?.isProbablyValidEmail() ?? false
   8.242 -    }
   8.243 -
   8.244 -    private var isValidPassword: Bool {
   8.245 -        if let pass = password {
   8.246 -            return pass.count > 0
   8.247 -        }
   8.248 -        return false
   8.249 -    }
   8.250 -
   8.251 -    // MARK: - Helpers for saving
   8.252 -
   8.253 -    /// Deletes the given server from the account, including its credentials
   8.254 -    /// and entries in the key chain.
   8.255 -    private func delete(server: CdServer, fromAccount: CdAccount) {
   8.256 -        if let creds = server.credentials {
   8.257 -            if let key = creds.key {
   8.258 -                KeyChain.updateCreateOrDelete(password: nil, forKey: key)
   8.259 -            }
   8.260 -            server.credentials = nil
   8.261 -            creds.delete()
   8.262 -        }
   8.263 -        fromAccount.removeFromServers(server)
   8.264 -    }
   8.265 -
   8.266 -    private func findOrCreateAccount(context: NSManagedObjectContext,
   8.267 -                                     identity: CdIdentity) -> CdAccount {
   8.268 -        let p = NSPredicate(
   8.269 -            format: "%K = %@" , CdAccount.RelationshipName.identity, identity)
   8.270 -        if let cdAccount = CdAccount.first(predicate: p, in: context) {
   8.271 -            return cdAccount
   8.272 -        } else {
   8.273 -            let cdAccount = CdAccount.create(context: context)
   8.274 -            cdAccount.identity = identity
   8.275 -            return cdAccount
   8.276 -        }
   8.277 -    }
   8.278 -
   8.279 -    private func updateOrCreateOwnIdentity(context: NSManagedObjectContext,
   8.280 -                                           address: String?,
   8.281 -                                           userName: String?) -> CdIdentity {
   8.282 -        if let theAddress = address,
   8.283 -            let identity = CdIdentity.search(address: theAddress) {
   8.284 -            update(identity: identity, address: address, userName: userName)
   8.285 -            return identity
   8.286 -        } else {
   8.287 -        let cdId = CdIdentity.create(context: context)
   8.288 -            update(identity: cdId, address: address, userName: userName)
   8.289 -            return cdId
   8.290 -        }
   8.291 -    }
   8.292 -
   8.293 -    private func update(identity: CdIdentity,
   8.294 -                        address: String?,
   8.295 -                        userName: String?) {
   8.296 -        identity.address = address
   8.297 -        identity.userName = userName
   8.298 -        identity.userID = CdIdentity.pEpOwnUserID
   8.299 -    }
   8.300 -
   8.301 -    /// Create credentials for the given parameters.
   8.302 -    ///
   8.303 -    /// - Note: There is either an ordinary password, so a key chain entry
   8.304 -    ///         gets produced, or an access token (for OAUTH2),
   8.305 -    ///         in which case the token gets persisted into the key chain.
   8.306 -    private func createCredentials(context: NSManagedObjectContext,
   8.307 -                                   loginName: String?,
   8.308 -                                   address: String?,
   8.309 -                                   password: String?,
   8.310 -                                   accessToken: OAuth2AccessTokenProtocol?)
   8.311 -        -> CdServerCredentials {
   8.312 -            let credentials = CdServerCredentials.create(context: context)
   8.313 -            credentials.loginName = loginName ?? address
   8.314 -
   8.315 -            let keyChainId = UUID().uuidString
   8.316 -            var payload: String? = nil
   8.317 -            if let token = accessToken {
   8.318 -                payload = token.persistBase64Encoded()
   8.319 -            } else {
   8.320 -                payload = password
   8.321 -            }
   8.322 -
   8.323 -            KeyChain.updateCreateOrDelete(password: payload, forKey: keyChainId)
   8.324 -            credentials.key = keyChainId
   8.325 -
   8.326 -            return credentials
   8.327 -    }
   8.328 -
   8.329 -    private func createServer(context: NSManagedObjectContext,
   8.330 -                              address: String,
   8.331 -                              port: UInt16,
   8.332 -                              serverType: Server.ServerType,
   8.333 -                              authMethod: AuthMethod?,
   8.334 -                              trusted: Bool,
   8.335 -                              transport: ConnectionTransport) -> CdServer {
   8.336 -        let server = CdServer.create(context: context)
   8.337 -        update(server: server,
   8.338 -               address: address,
   8.339 -               port: port,
   8.340 -               serverType: serverType,
   8.341 -               authMethod: authMethod,
   8.342 -               trusted: trusted,
   8.343 -               transport: transport)
   8.344 -        return server
   8.345 -    }
   8.346 -
   8.347 -    private func update(server: CdServer,
   8.348 -                        address: String,
   8.349 -                        port: UInt16,
   8.350 -                        serverType: Server.ServerType,
   8.351 -                        authMethod: AuthMethod?,
   8.352 -                        trusted: Bool,
   8.353 -                        transport: ConnectionTransport) {
   8.354 -        server.address = address
   8.355 -        server.port = NSNumber.init(value: port)
   8.356 -        server.authMethod = authMethod?.rawValue
   8.357 -        server.serverType = serverType
   8.358 -        server.trusted = trusted
   8.359 -        server.transport = transport.toServerTransport()
   8.360 -        server.serverType = serverType
   8.361 -    }
   8.362 -
   8.363 -    // MARK: - Legacy
   8.364 -
   8.365 -    /// Returns an Account instance filled with data of self.
   8.366 -    /// It does not deal with Core Data (does not persist).
   8.367 -    /// Only data from this model is taken into account, not needsVerivication or others.
   8.368 -    ///
   8.369 -    /// - Returns: filled Account
   8.370 -    /// - Throws: AccountSettingsUserInputError
   8.371 -    public func account() throws -> Account {
   8.372 -        guard let address = self.address, address != "" else {
   8.373 -            let msg = NSLocalizedString("E-mail must not be empty",
   8.374 -                                        comment: "Alert message for empty e-mail address field")
   8.375 -            throw AccountSettingsUserInputError.invalidInputEmailAddress(localizedMessage: msg)
   8.376 -        }
   8.377 -
   8.378 -        guard let userName = self.userName, userName != "" else {
   8.379 -            let msg = NSLocalizedString("Username must not be empty",
   8.380 -                                        comment: "Alert message for empty username")
   8.381 -            throw AccountSettingsUserInputError.invalidInputUserName(localizedMessage: msg)
   8.382 -        }
   8.383 -
   8.384 -        guard let serverIMAP = self.serverIMAP, serverIMAP != "" else {
   8.385 -            let msg = NSLocalizedString("IMAP server must not be empty",
   8.386 -                                        comment: "Alert message for empty IMAP server")
   8.387 -            throw AccountSettingsUserInputError.invalidInputServer(localizedMessage: msg)
   8.388 -        }
   8.389 -        guard let serverSMTP = self.serverSMTP, serverSMTP != "" else {
   8.390 -            let msg = NSLocalizedString("SMTP server must not be empty",
   8.391 -                                        comment: "Alert message for empty SMTP server")
   8.392 -            throw AccountSettingsUserInputError.invalidInputServer(localizedMessage: msg)
   8.393 -        }
   8.394 -
   8.395 -        let identity = Identity.create(address: address, userID: nil, userName: userName,
   8.396 -                                       isMySelf: true)
   8.397 -
   8.398 -        var logIn = self.loginName ?? address
   8.399 -        if logIn.isEmpty {
   8.400 -            logIn = address
   8.401 -        }
   8.402 -
   8.403 -        let thePassword = accessToken?.persistBase64Encoded() ?? password
   8.404 -        // The key is created upfront, in case of SASL XOAUTH2, where we want to link
   8.405 -        // the token to the same key
   8.406 -        let credentialsImap = ServerCredentials.create(loginName: logIn,
   8.407 -                                                       key: accessToken?.keyChainID)
   8.408 -        credentialsImap.password = thePassword
   8.409 -
   8.410 -        let imapServer = Server.create(serverType: .imap, port: self.portIMAP, address: serverIMAP,
   8.411 -                                       transport: self.transportIMAP.toServerTransport(),
   8.412 -                                       authMethod: authMethod?.rawValue,
   8.413 -                                       credentials: credentialsImap)
   8.414 -
   8.415 -        let credentialsSmtp: ServerCredentials
   8.416 -        if authMethod == .saslXoauth2 {
   8.417 -            // In case of SASL XOAUTH2, there will be only 1 credential, with our created key
   8.418 -            credentialsSmtp = credentialsImap
   8.419 -        } else {
   8.420 -            credentialsSmtp = ServerCredentials.create(loginName: logIn, key: accessToken?.keyChainID)
   8.421 -            credentialsSmtp.password = thePassword
   8.422 -        }
   8.423 -
   8.424 -        let smtpServer = Server.create(serverType: .smtp,
   8.425 -                                       port: self.portSMTP,
   8.426 -                                       address: serverSMTP,
   8.427 -                                       transport: self.transportSMTP.toServerTransport(),
   8.428 -                                       authMethod: authMethod?.rawValue,
   8.429 -                                       credentials: credentialsSmtp)
   8.430 -
   8.431 -        let account = Account(user: identity, servers: [imapServer, smtpServer])
   8.432 -        return account
   8.433 -    }
   8.434 -
   8.435 -    // MARK: - Internal (Behaviour)
   8.436 -
   8.437 -    private func checkSuccess() {
   8.438 -        guard let theImapResult = imapResult, let theSmtpResult = smtpResult else {
   8.439 -            return
   8.440 -        }
   8.441 -
   8.442 -        switch theImapResult {
   8.443 -        case .failure(let error):
   8.444 -            verifiableAccountDelegate?.didEndVerification(result: .failure(error))
   8.445 -        case .success(()):
   8.446 -            switch theSmtpResult {
   8.447 -            case .failure(let error):
   8.448 -                verifiableAccountDelegate?.didEndVerification(result: .failure(error))
   8.449 -            case .success(()):
   8.450 -                verifiableAccountDelegate?.didEndVerification(result: .success(()))
   8.451 -            }
   8.452 -        }
   8.453 -    }
   8.454 -}
   8.455 -
   8.456 -extension VerifiableAccount: VerifiableAccountIMAPDelegate {
   8.457 -    public func verified(verifier: VerifiableAccountIMAP,
   8.458 -                         basicConnectInfo: BasicConnectInfo,
   8.459 -                         result: Result<Void, Error>) {
   8.460 -        verifier.verifiableAccountDelegate = nil
   8.461 -        syncQueue.async { [weak self] in
   8.462 -            self?.imapResult = result
   8.463 -            self?.checkSuccess()
   8.464 -        }
   8.465 -    }
   8.466 -}
   8.467 -
   8.468 -extension VerifiableAccount: VerifiableAccountSMTPDelegate {
   8.469 -    public func verified(verifier: VerifiableAccountSMTP,
   8.470 -                         basicConnectInfo: BasicConnectInfo,
   8.471 -                         result: Result<Void, Error>) {
   8.472 -        verifier.verifiableAccountDelegate = nil
   8.473 -        syncQueue.async { [weak self] in
   8.474 -            self?.smtpResult = result
   8.475 -            self?.checkSuccess()
   8.476 -        }
   8.477 -    }
   8.478 -}
     9.1 --- a/pEpForiOS/Models/VerifiableAccount/VerifiableAccountIMAP.swift	Wed May 08 12:31:03 2019 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,65 +0,0 @@
     9.4 -//
     9.5 -//  VerifiableAccountIMAP.swift
     9.6 -//  pEp
     9.7 -//
     9.8 -//  Created by Dirk Zimmermann on 16.04.19.
     9.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
    9.10 -//
    9.11 -
    9.12 -import Foundation
    9.13 -
    9.14 -import PantomimeFramework
    9.15 -import MessageModel
    9.16 -import pEpIOSToolbox
    9.17 -
    9.18 -public protocol VerifiableAccountIMAPDelegate: class {
    9.19 -    func verified(verifier: VerifiableAccountIMAP,
    9.20 -                  basicConnectInfo: BasicConnectInfo,
    9.21 -                  result: Result<Void, Error>)
    9.22 -}
    9.23 -
    9.24 -/// Helper for `VerifiableAccount` (verifies IMAP servers).
    9.25 -public class VerifiableAccountIMAP {
    9.26 -    public weak var verifiableAccountDelegate: VerifiableAccountIMAPDelegate?
    9.27 -
    9.28 -    private var sync: ImapSync?
    9.29 -    private var syncDelegate: VerifiableAccountSyncDelegate?
    9.30 -    private var basicConnectInfo: BasicConnectInfo?
    9.31 -
    9.32 -    /// Tries to verify the given IMAP account.
    9.33 -    public func verify(basicConnectInfo: BasicConnectInfo) {
    9.34 -        self.basicConnectInfo = basicConnectInfo
    9.35 -
    9.36 -        let theSyncDelegate = VerifiableAccountSyncDelegate(errorHandler: self)
    9.37 -        syncDelegate = theSyncDelegate
    9.38 -
    9.39 -        sync = ImapSync(connectInfo: basicConnectInfo)
    9.40 -        sync?.delegate = syncDelegate
    9.41 -        sync?.start()
    9.42 -    }
    9.43 -
    9.44 -    func authenticationCompleted(_ sync: ImapSync, notification: Notification?) {
    9.45 -        self.sync = nil
    9.46 -
    9.47 -        verifiableAccountDelegate?.verified(
    9.48 -            verifier: self,
    9.49 -            basicConnectInfo: BasicConnectInfo.force(basicConnectInfo: basicConnectInfo),
    9.50 -            result: .success(()))
    9.51 -    }
    9.52 -}
    9.53 -
    9.54 -extension VerifiableAccountIMAP: ImapSyncDelegateErrorHandlerProtocol {
    9.55 -    public func handle(error: Error) {
    9.56 -        verifiableAccountDelegate?.verified(
    9.57 -            verifier: self,
    9.58 -            basicConnectInfo: BasicConnectInfo.force(basicConnectInfo: basicConnectInfo),
    9.59 -            result: .failure(error))
    9.60 -    }
    9.61 -}
    9.62 -
    9.63 -class VerifiableAccountSyncDelegate: DefaultImapSyncDelegate {
    9.64 -    override func authenticationCompleted(_ sync: ImapSync, notification: Notification?) {
    9.65 -        (errorHandler as? VerifiableAccountIMAP)?.authenticationCompleted(
    9.66 -            sync, notification: notification)
    9.67 -    }
    9.68 -}
    10.1 --- a/pEpForiOS/Models/VerifiableAccount/VerifiableAccountProtocol+UI.swift	Wed May 08 12:31:03 2019 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,33 +0,0 @@
    10.4 -//
    10.5 -//  VerifiableAccountProtocol+UI.swift
    10.6 -//  pEp
    10.7 -//
    10.8 -//  Created by Dirk Zimmermann on 18.04.19.
    10.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   10.10 -//
   10.11 -
   10.12 -import Foundation
   10.13 -
   10.14 -import MessageModel
   10.15 -
   10.16 -/// Used by the UI.
   10.17 -public extension VerifiableAccountProtocol {
   10.18 -    public var isValidName: Bool {
   10.19 -        return (userName?.count ?? 0) >= 1
   10.20 -    }
   10.21 -
   10.22 -    public var isValidUser: Bool {
   10.23 -        return isValidName && isValidEmail && isValidPassword
   10.24 -    }
   10.25 -
   10.26 -    private var isValidEmail: Bool {
   10.27 -        return address?.isProbablyValidEmail() ?? false
   10.28 -    }
   10.29 -
   10.30 -    private var isValidPassword: Bool {
   10.31 -        if let pass = password {
   10.32 -            return pass.count > 0
   10.33 -        }
   10.34 -        return false
   10.35 -    }
   10.36 -}
    11.1 --- a/pEpForiOS/Models/VerifiableAccount/VerifiableAccountSMTP.swift	Wed May 08 12:31:03 2019 +0200
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,131 +0,0 @@
    11.4 -//
    11.5 -//  VerifiableAccountSMTP.swift
    11.6 -//  pEp
    11.7 -//
    11.8 -//  Created by Dirk Zimmermann on 17.04.19.
    11.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   11.10 -//
   11.11 -
   11.12 -import Foundation
   11.13 -
   11.14 -import PantomimeFramework
   11.15 -import MessageModel
   11.16 -import pEpIOSToolbox
   11.17 -
   11.18 -public protocol VerifiableAccountSMTPDelegate: class {
   11.19 -    func verified(verifier: VerifiableAccountSMTP,
   11.20 -                  basicConnectInfo: BasicConnectInfo,
   11.21 -                  result: Result<Void, Error>)
   11.22 -}
   11.23 -
   11.24 -/// Helper for `VerifiableAccount` (verifies SMTP servers).
   11.25 -public class VerifiableAccountSMTP {
   11.26 -    public weak var verifiableAccountDelegate: VerifiableAccountSMTPDelegate?
   11.27 -
   11.28 -    private var smtpSend: SmtpSend?
   11.29 -    private var basicConnectInfo: BasicConnectInfo?
   11.30 -
   11.31 -    /// Tries to verify the given IMAP account.
   11.32 -    public func verify(basicConnectInfo: BasicConnectInfo) {
   11.33 -        self.basicConnectInfo = basicConnectInfo
   11.34 -
   11.35 -        smtpSend = SmtpSend(connectInfo: basicConnectInfo)
   11.36 -        smtpSend?.delegate = self
   11.37 -        smtpSend?.start()
   11.38 -    }
   11.39 -}
   11.40 -
   11.41 -extension VerifiableAccountSMTP: SmtpSendDelegate {
   11.42 -    private func forcedConnectInfo() -> BasicConnectInfo {
   11.43 -        return BasicConnectInfo.force(basicConnectInfo: basicConnectInfo)
   11.44 -    }
   11.45 -
   11.46 -    private func notifyUnexpectedCallback(name: String) {
   11.47 -        let error = SmtpSendError.badResponse(name)
   11.48 -        verifiableAccountDelegate?.verified(
   11.49 -            verifier: self,
   11.50 -            basicConnectInfo: forcedConnectInfo(),
   11.51 -            result: .failure(error))
   11.52 -    }
   11.53 -
   11.54 -    private func notify(error: Error) {
   11.55 -        verifiableAccountDelegate?.verified(
   11.56 -            verifier: self,
   11.57 -            basicConnectInfo: forcedConnectInfo(),
   11.58 -            result: .failure(error))
   11.59 -    }
   11.60 -
   11.61 -    public func messageSent(_ smtp: SmtpSend, theNotification: Notification?) {
   11.62 -        notifyUnexpectedCallback(name: #function)
   11.63 -    }
   11.64 -
   11.65 -    public func messageNotSent(_ smtp: SmtpSend, theNotification: Notification?) {
   11.66 -        notifyUnexpectedCallback(name: #function)
   11.67 -    }
   11.68 -
   11.69 -    public func transactionInitiationCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   11.70 -        notifyUnexpectedCallback(name: #function)
   11.71 -    }
   11.72 -
   11.73 -    public func transactionInitiationFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   11.74 -        notifyUnexpectedCallback(name: #function)
   11.75 -    }
   11.76 -
   11.77 -    public func recipientIdentificationCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   11.78 -        notifyUnexpectedCallback(name: #function)
   11.79 -    }
   11.80 -
   11.81 -    public func recipientIdentificationFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   11.82 -        notifyUnexpectedCallback(name: #function)
   11.83 -    }
   11.84 -
   11.85 -    public func transactionResetCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   11.86 -        notifyUnexpectedCallback(name: #function)
   11.87 -    }
   11.88 -
   11.89 -    public func transactionResetFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   11.90 -        notifyUnexpectedCallback(name: #function)
   11.91 -    }
   11.92 -
   11.93 -    public func authenticationCompleted(_ smtp: SmtpSend, theNotification: Notification?) {
   11.94 -    }
   11.95 -
   11.96 -    public func authenticationFailed(_ smtp: SmtpSend, theNotification: Notification?) {
   11.97 -        notify(error: SmtpSendError.authenticationFailed(
   11.98 -            #function,
   11.99 -            forcedConnectInfo().accountEmailAddress))
  11.100 -    }
  11.101 -
  11.102 -    public func connectionEstablished(_ smtp: SmtpSend, theNotification: Notification?) {}
  11.103 -
  11.104 -    public func connectionLost(_ smtp: SmtpSend, theNotification: Notification?) {
  11.105 -        notify(error: SmtpSendError.connectionLost(#function))
  11.106 -    }
  11.107 -
  11.108 -    public func connectionTerminated(_ smtp: SmtpSend, theNotification: Notification?) {
  11.109 -        notify(error: SmtpSendError.connectionTerminated(#function))
  11.110 -    }
  11.111 -
  11.112 -    public func connectionTimedOut(_ smtp: SmtpSend, theNotification: Notification?) {
  11.113 -        notify(error: SmtpSendError.connectionTimedOut(#function))
  11.114 -    }
  11.115 -
  11.116 -    public func badResponse(_ smtp: SmtpSend, response: String?) {
  11.117 -        notify(error: SmtpSendError.badResponse(#function))
  11.118 -    }
  11.119 -
  11.120 -    public func requestCancelled(_ smtp: SmtpSend, theNotification: Notification?) {
  11.121 -        notifyUnexpectedCallback(name: #function)
  11.122 -    }
  11.123 -
  11.124 -    public func serviceInitialized(_ smtp: SmtpSend, theNotification: Notification?) {
  11.125 -        verifiableAccountDelegate?.verified(
  11.126 -            verifier: self,
  11.127 -            basicConnectInfo: forcedConnectInfo(),
  11.128 -            result: .success(()))
  11.129 -    }
  11.130 -
  11.131 -    public func serviceReconnected(_ smtp: SmtpSend, theNotification: Notification?) {
  11.132 -        notifyUnexpectedCallback(name: #function)
  11.133 -    }
  11.134 -}
    12.1 --- a/pEpForiOS/UI/Compose/Cells/AttachmentCell/AttachmentViewModel.swift	Wed May 08 12:31:03 2019 +0200
    12.2 +++ b/pEpForiOS/UI/Compose/Cells/AttachmentCell/AttachmentViewModel.swift	Fri May 17 14:16:55 2019 +0200
    12.3 @@ -9,20 +9,21 @@
    12.4  import MessageModel
    12.5  
    12.6  class AttachmentViewModel: CellViewModel {
    12.7 +    public let attachment: Attachment
    12.8 +    private lazy var mimeTypeUtils = MimeTypeUtils()
    12.9 +
   12.10 +    init(attachment: Attachment) {
   12.11 +        self.attachment = attachment
   12.12 +    }
   12.13 +
   12.14      static let defaultFileName = NSLocalizedString("unknown",
   12.15 -                                            comment:
   12.16 +                                                   comment:
   12.17          "Displayed attachment filename if unknown")
   12.18      public var fileName: String {
   12.19          return attachment.fileName ?? AttachmentViewModel.defaultFileName
   12.20      }
   12.21 +
   12.22      public var fileExtension: String {
   12.23 -        return mimeTypeUtil?.fileExtension(mimeType: attachment.mimeType) ?? ""
   12.24 -    }
   12.25 -
   12.26 -    public let attachment: Attachment
   12.27 -    private let mimeTypeUtil = MimeTypeUtil()
   12.28 -
   12.29 -    init(attachment: Attachment) {
   12.30 -        self.attachment = attachment
   12.31 +        return mimeTypeUtils?.fileExtension(fromMimeType: attachment.mimeType) ?? ""
   12.32      }
   12.33  }
    13.1 --- a/pEpForiOS/UI/Compose/Util/DocumentAttachmentPickerViewController/DocumentAttachmentPickerViewModel.swift	Wed May 08 12:31:03 2019 +0200
    13.2 +++ b/pEpForiOS/UI/Compose/Util/DocumentAttachmentPickerViewController/DocumentAttachmentPickerViewModel.swift	Fri May 17 14:16:55 2019 +0200
    13.3 @@ -20,6 +20,7 @@
    13.4      lazy private var attachmentFileIOQueue = DispatchQueue(label:
    13.5          "security.pep.DocumentAttachmentPickerViewModel.attachmentFileIOQueue",
    13.6                                                             qos: .userInitiated)
    13.7 +    private let mimeUtils = MimeTypeUtils()
    13.8      weak public var resultDelegate: DocumentAttachmentPickerViewModelResultDelegate?
    13.9  
   13.10      public init(resultDelegate: DocumentAttachmentPickerViewModelResultDelegate? = nil) {
   13.11 @@ -59,7 +60,7 @@
   13.12      private func createAttachment(forSecurityScopedResource resourceUrl: URL,
   13.13                                    completion: @escaping (Attachment?) -> Void) {
   13.14          let cfUrl = resourceUrl as CFURL
   13.15 -        attachmentFileIOQueue.async {
   13.16 +        attachmentFileIOQueue.async { [weak self] in
   13.17              CFURLStartAccessingSecurityScopedResource(cfUrl)
   13.18              defer { CFURLStopAccessingSecurityScopedResource(cfUrl) }
   13.19              guard  let resourceData = try? Data(contentsOf: resourceUrl)  else {
   13.20 @@ -67,7 +68,8 @@
   13.21                  completion(nil)
   13.22                  return
   13.23              }
   13.24 -            let mimeType = resourceUrl.mimeType() ?? MimeTypeUtil.defaultMimeType
   13.25 +            let mimeType = self?.mimeUtils?.mimeType(fromURL: resourceUrl) ??
   13.26 +                MimeTypeUtils.MimesType.defaultMimeType
   13.27              let filename = resourceUrl.fileName(includingExtension: true)
   13.28              let attachment = Attachment.create(data: resourceData,
   13.29                                                 mimeType: mimeType,
    14.1 --- a/pEpForiOS/UI/Compose/Util/MediaAttachmentPickerProvider/MediaAttachmentPickerProviderViewModel.swift	Wed May 08 12:31:03 2019 +0200
    14.2 +++ b/pEpForiOS/UI/Compose/Util/MediaAttachmentPickerProvider/MediaAttachmentPickerProviderViewModel.swift	Fri May 17 14:16:55 2019 +0200
    14.3 @@ -23,6 +23,7 @@
    14.4          "security.pep.MediaAttachmentPickerProviderViewModel.attachmentFileIOQueue",
    14.5                                                             qos: .userInitiated)
    14.6      private var numVideosSelected = 0
    14.7 +    private let mimeTypeUtils = MimeTypeUtils()
    14.8      weak public var resultDelegate: MediaAttachmentPickerProviderViewModelResultDelegate?
    14.9  
   14.10      public init(resultDelegate: MediaAttachmentPickerProviderViewModelResultDelegate?) {
   14.11 @@ -83,7 +84,7 @@
   14.12                                    completion: @escaping (Attachment?) -> Void) {
   14.13          attachmentFileIOQueue.async { [weak self] in
   14.14              guard let me = self else {
   14.15 -                Log.shared.errorAndCrash("Lost MySelf")
   14.16 +                Log.shared.lostMySelf()
   14.17                  return
   14.18              }
   14.19              guard let resourceData = try? Data(contentsOf: resourceUrl) else {
   14.20 @@ -91,7 +92,8 @@
   14.21                  completion(nil)
   14.22                  return
   14.23              }
   14.24 -            let mimeType = resourceUrl.mimeType() ?? MimeTypeUtil.defaultMimeType
   14.25 +            let mimeType = me.mimeTypeUtils?.mimeType(fromURL: resourceUrl) ??
   14.26 +                MimeTypeUtils.MimesType.defaultMimeType
   14.27              let filename = me.fileName(forVideoAt: resourceUrl)
   14.28              let attachment =  Attachment.create(data: resourceData,
   14.29                                                  mimeType: mimeType,
   14.30 @@ -111,9 +113,8 @@
   14.31          return fileName + numDisplay + "." + fileExtension
   14.32      }
   14.33  
   14.34 -    private func createAttachment(forAssetWithUrl assetUrl: URL,
   14.35 -                                  image: UIImage) -> Attachment {
   14.36 -        let mimeType = assetUrl.mimeType() ?? MimeTypeUtil.defaultMimeType
   14.37 +    private func createAttachment(forAssetWithUrl assetUrl: URL, image: UIImage) -> Attachment {
   14.38 +        let mimeType = mimeTypeUtils?.mimeType(fromURL: assetUrl) ?? MimeTypeUtils.MimesType.defaultMimeType
   14.39          return Attachment.createFromAsset(mimeType: mimeType,
   14.40                                            assetUrl: assetUrl,
   14.41                                            image: image,
    15.1 --- a/pEpForiOS/UI/EmailDisplay/Background/AttachmentToLocalURLOperation.swift	Wed May 08 12:31:03 2019 +0200
    15.2 +++ b/pEpForiOS/UI/EmailDisplay/Background/AttachmentToLocalURLOperation.swift	Fri May 17 14:16:55 2019 +0200
    15.3 @@ -37,7 +37,7 @@
    15.4          
    15.5          var theURL = tmpDir.appendingPathComponent(fileName)
    15.6  
    15.7 -        if attachment.mimeType == "application/pdf" {
    15.8 +        if attachment.mimeType == MimeTypeUtils.MimesType.pdf {
    15.9              theURL = theURL.appendingPathExtension("pdf")
   15.10          }
   15.11          do {
    16.1 --- a/pEpForiOS/UI/EmailDisplay/Background/AttachmentsViewOperation.swift	Wed May 08 12:31:03 2019 +0200
    16.2 +++ b/pEpForiOS/UI/EmailDisplay/Background/AttachmentsViewOperation.swift	Fri May 17 14:16:55 2019 +0200
    16.3 @@ -16,7 +16,7 @@
    16.4          case docAttachment(Attachment)
    16.5      }
    16.6  
    16.7 -    let mimeTypes: MimeTypeUtil?
    16.8 +    let mimeTypes: MimeTypeUtils?
    16.9      let message: Message
   16.10  
   16.11      /**
   16.12 @@ -29,7 +29,7 @@
   16.13       */
   16.14      var attachmentsCount = 0
   16.15  
   16.16 -    init(mimeTypes: MimeTypeUtil?, message: Message) {
   16.17 +    init(mimeTypes: MimeTypeUtils?, message: Message) {
   16.18          self.mimeTypes = mimeTypes
   16.19          self.message = message
   16.20  
    17.1 --- a/pEpForiOS/UI/EmailDisplay/EmailViewController.swift	Wed May 08 12:31:03 2019 +0200
    17.2 +++ b/pEpForiOS/UI/EmailDisplay/EmailViewController.swift	Fri May 17 14:16:55 2019 +0200
    17.3 @@ -649,7 +649,8 @@
    17.4  
    17.5      func didCreateLocally(attachment: Attachment, url: URL, cell: MessageCell, location: CGPoint,
    17.6                            inView: UIView?) {
    17.7 -        if attachment.mimeType == "application/pdf" && QLPreviewController.canPreview(url as QLPreviewItem){
    17.8 +        if attachment.mimeType == MimeTypeUtils.MimesType.pdf
    17.9 +            && QLPreviewController.canPreview(url as QLPreviewItem){
   17.10                  selectedAttachmentURL = url
   17.11                  let previewController = QLPreviewController()
   17.12                  previewController.dataSource = self
    18.1 --- a/pEpForiOS/UI/EmailDisplay/Stuff that is named Compose but is used only in EmailView/ComposeDataSource.swift	Wed May 08 12:31:03 2019 +0200
    18.2 +++ b/pEpForiOS/UI/EmailDisplay/Stuff that is named Compose but is used only in EmailView/ComposeDataSource.swift	Fri May 17 14:16:55 2019 +0200
    18.3 @@ -66,7 +66,7 @@
    18.4              let fileExtesion: String?
    18.5          }
    18.6          public private(set) var attachments = [Attachment]()
    18.7 -        let mimeTypeUtil = MimeTypeUtil()
    18.8 +        let mimeTypeUtils = MimeTypeUtils()
    18.9  
   18.10          func count() -> Int {
   18.11              return attachments.count
   18.12 @@ -79,7 +79,7 @@
   18.13              }
   18.14              let attachment = attachments[index]
   18.15              return Row(fileName: attachment.fileName,
   18.16 -                       fileExtesion: mimeTypeUtil?.fileExtension(mimeType: attachment.mimeType) ?? "")
   18.17 +                       fileExtesion: mimeTypeUtils?.fileExtension(fromMimeType: attachment.mimeType) ?? "")
   18.18          }
   18.19  
   18.20          /// Adds an attachment to the data source and returns the index it has been inserted in.
    19.1 --- a/pEpForiOS/UI/EmailDisplay/Util/AttachmentsViewHelper.swift	Wed May 08 12:31:03 2019 +0200
    19.2 +++ b/pEpForiOS/UI/EmailDisplay/Util/AttachmentsViewHelper.swift	Fri May 17 14:16:55 2019 +0200
    19.3 @@ -29,7 +29,7 @@
    19.4          }
    19.5      }
    19.6  
    19.7 -    let mimeTypes = MimeTypeUtil()
    19.8 +    let mimeTypes = MimeTypeUtils()
    19.9      var buildOp: AttachmentsViewOperation?
   19.10      let operationQueue = OperationQueue()
   19.11  
   19.12 @@ -46,7 +46,7 @@
   19.13              attachment.fileName?.splitFileExtension() ?? (Constants.defaultFileName, nil)
   19.14          return AttachmentSummaryView.AttachmentInfo(
   19.15              filename: name.extractFileNameOrCid(),
   19.16 -            theExtension: ext ?? mimeTypes?.fileExtension(mimeType: attachment.mimeType))
   19.17 +            theExtension: ext ?? mimeTypes?.fileExtension(fromMimeType: attachment.mimeType))
   19.18      }
   19.19  
   19.20      func opFinished(theBuildOp: AttachmentsViewOperation) {
    20.1 --- a/pEpForiOS/UI/Login/LoginViewController.swift	Wed May 08 12:31:03 2019 +0200
    20.2 +++ b/pEpForiOS/UI/Login/LoginViewController.swift	Fri May 17 14:16:55 2019 +0200
    20.3 @@ -77,18 +77,12 @@
    20.4          }
    20.5      }
    20.6  
    20.7 -    /**
    20.8 -     The last account input as determined by LAS, and delivered via didVerify.
    20.9 -     */
   20.10 -    var lastAccountInput: VerifiableAccountProtocol?
   20.11 -
   20.12      override var prefersStatusBarHidden: Bool {
   20.13          return true
   20.14      }
   20.15  
   20.16      override func didSetAppConfig() {
   20.17          super.didSetAppConfig()
   20.18 -        loginViewModel.verificationService = VerifiableAccount()
   20.19      }
   20.20  
   20.21      override func viewDidLoad() {
   20.22 @@ -291,11 +285,7 @@
   20.23                  let vc = navVC.topViewController as? UserInfoTableViewController {
   20.24                  vc.appConfig = appConfig
   20.25  
   20.26 -                if let accountInput = lastAccountInput {
   20.27 -                    vc.model = accountInput // give the user some prefilled data in manual mode
   20.28 -                }
   20.29 -
   20.30 -                // Overwrite with more recent data that we might have (in case it was changed)
   20.31 +                // Give the next model what we know.
   20.32                  vc.model.address = emailAddress.text
   20.33                  vc.model.password = password.text
   20.34                  vc.model.userName = user.text
   20.35 @@ -309,26 +299,21 @@
   20.36  // MARK: - AccountVerificationResultDelegate
   20.37  
   20.38  extension LoginViewController: AccountVerificationResultDelegate {
   20.39 -    func didVerify(result: AccountVerificationResult,
   20.40 -                   accountInput: VerifiableAccountProtocol?) {
   20.41 +    func didVerify(result: AccountVerificationResult) {
   20.42          GCD.onMain() { [weak self] in
   20.43              guard let me = self else {
   20.44                  Log.shared.errorAndCrash("Lost MySelf")
   20.45                  return
   20.46              }
   20.47 -            me.lastAccountInput = nil
   20.48              switch result {
   20.49              case .ok:
   20.50                  me.delegate?.loginViewControllerDidCreateNewAccount(me)
   20.51                  me.navigationController?.dismiss(animated: true)
   20.52              case .imapError(let err):
   20.53 -                me.lastAccountInput = accountInput
   20.54                  me.handleLoginError(error: err, offerManualSetup: true)
   20.55              case .smtpError(let err):
   20.56 -                me.lastAccountInput = accountInput
   20.57                  me.handleLoginError(error: err, offerManualSetup: true)
   20.58              case .noImapConnectData, .noSmtpConnectData:
   20.59 -                me.lastAccountInput = accountInput
   20.60                  me.handleLoginError(error: LoginViewController.LoginError.noConnectData,
   20.61                                      offerManualSetup: true)
   20.62              }
    21.1 --- a/pEpForiOS/UI/Login/ViewModel/LoginViewModel.swift	Wed May 08 12:31:03 2019 +0200
    21.2 +++ b/pEpForiOS/UI/Login/ViewModel/LoginViewModel.swift	Fri May 17 14:16:55 2019 +0200
    21.3 @@ -25,7 +25,7 @@
    21.4  
    21.5      /// Holding both the data of the current account in verification,
    21.6      /// and also the implementation of the verification.
    21.7 -    var verificationService: VerifiableAccountProtocol?
    21.8 +    var verifiableAccount: VerifiableAccountProtocol?
    21.9  
   21.10      /** If the last login attempt was via OAuth2, this will collect temporary parameters */
   21.11      private var lastOAuth2Parameters: OAuth2Parameters?
   21.12 @@ -52,8 +52,8 @@
   21.13  
   21.14      let qualifyServerService = QualifyServerIsLocalService()
   21.15  
   21.16 -    init(verificationService: VerifiableAccountProtocol? = nil) {
   21.17 -        self.verificationService = verificationService
   21.18 +    init(verifiableAccount: VerifiableAccountProtocol? = nil) {
   21.19 +        self.verifiableAccount = verifiableAccount
   21.20      }
   21.21  
   21.22      func isThereAnAccount() -> Bool {
   21.23 @@ -116,7 +116,7 @@
   21.24              let smtpTransport = ConnectionTransport(
   21.25                  accountSettingsTransport: outgoingServer.transport, smtpPort: outgoingServer.port)
   21.26  
   21.27 -            var newAccount = verificationService ?? VerifiableAccount()
   21.28 +            var newAccount = verifiableAccount ?? VerifiableAccount()
   21.29  
   21.30              newAccount.verifiableAccountDelegate = self
   21.31              newAccount.address = accountName
   21.32 @@ -137,7 +137,7 @@
   21.33              newAccount.transportSMTP = smtpTransport
   21.34              newAccount.trustedImapServer = false
   21.35  
   21.36 -            verificationService = newAccount
   21.37 +            verifiableAccount = newAccount
   21.38              verifyAccount(model: newAccount)
   21.39          }
   21.40      }
   21.41 @@ -147,7 +147,7 @@
   21.42      /// - Parameter model: account data
   21.43      /// - Throws: AccountVerificationError
   21.44      func verifyAccount(model: VerifiableAccountProtocol?) {
   21.45 -        if let imapServer = verificationService?.serverIMAP {
   21.46 +        if let imapServer = verifiableAccount?.serverIMAP {
   21.47              qualifyServerService.delegate = self
   21.48              qualifyServerService.qualify(serverName: imapServer)
   21.49          } else {
   21.50 @@ -156,12 +156,13 @@
   21.51      }
   21.52  
   21.53      func accountHasBeenQualified(trusted: Bool) {
   21.54 -        guard var theVerificationService = verificationService else {
   21.55 +        guard var theVerificationService = verifiableAccount else {
   21.56              Log.shared.errorAndCrash("no VerificationService")
   21.57              return
   21.58          }
   21.59  
   21.60          theVerificationService.trustedImapServer = trusted
   21.61 +
   21.62          do {
   21.63              try theVerificationService.verify()
   21.64          } catch {
   21.65 @@ -222,25 +223,17 @@
   21.66  
   21.67  extension LoginViewModel: VerifiableAccountDelegate {
   21.68      func informAccountVerificationResultDelegate(error: Error?) {
   21.69 -        guard let theService = verificationService else {
   21.70 -            Log.shared.error(
   21.71 -                "Lost the verificationService, was about to inform the delegate")
   21.72 -            if let err = error {
   21.73 -                Log.shared.log("%@", err.localizedDescription)
   21.74 -            }
   21.75 -            return
   21.76 -        }
   21.77          if let imapError = error as? ImapSyncError {
   21.78              accountVerificationResultDelegate?.didVerify(
   21.79 -                result: .imapError(imapError), accountInput: theService)
   21.80 +                result: .imapError(imapError))
   21.81          } else if let smtpError = error as? SmtpSendError {
   21.82              accountVerificationResultDelegate?.didVerify(
   21.83 -                result: .smtpError(smtpError), accountInput: theService)
   21.84 +                result: .smtpError(smtpError))
   21.85          } else {
   21.86              if let theError = error {
   21.87                  Log.shared.errorAndCrash("%@", theError.localizedDescription)
   21.88              } else {
   21.89 -                accountVerificationResultDelegate?.didVerify(result: .ok, accountInput: theService)
   21.90 +                accountVerificationResultDelegate?.didVerify(result: .ok)
   21.91              }
   21.92          }
   21.93      }
   21.94 @@ -249,7 +242,7 @@
   21.95          switch result {
   21.96          case .success(()):
   21.97              do {
   21.98 -                try verificationService?.save()
   21.99 +                try verifiableAccount?.save()
  21.100                  informAccountVerificationResultDelegate(error: nil)
  21.101                  mySelfer?.startMySelf()
  21.102              } catch {
    22.1 --- a/pEpForiOS/UI/ManualLogin/ImapSetup/IMAPSettingsTableViewController.swift	Wed May 08 12:31:03 2019 +0200
    22.2 +++ b/pEpForiOS/UI/ManualLogin/ImapSetup/IMAPSettingsTableViewController.swift	Fri May 17 14:16:55 2019 +0200
    22.3 @@ -32,7 +32,9 @@
    22.4  
    22.5      let viewWidthAligner = ViewWidthsAligner()
    22.6  
    22.7 -    var model: VerifiableAccountProtocol!
    22.8 +    /// - Note: This VC doesn't have a view model yet, so this is used for the model.
    22.9 +    var model: VerifiableAccountProtocol?
   22.10 +
   22.11      var fields = [UITextField]()
   22.12      var responder = 0
   22.13  
   22.14 @@ -59,13 +61,15 @@
   22.15  
   22.16      override func viewDidAppear(_ animated: Bool) {
   22.17          super.viewDidAppear(animated)
   22.18 -        firstResponder(model.serverIMAP == nil)
   22.19 +        firstResponder(model?.serverIMAP == nil)
   22.20      }
   22.21  
   22.22      private func updateView() {
   22.23 -        serverValue.text = model.serverIMAP
   22.24 -        portValue.text = String(model.portIMAP)
   22.25 -        transportSecurity.setTitle(model.transportIMAP.localizedString(), for: UIControl.State())
   22.26 +        serverValue.text = model?.serverIMAP
   22.27 +        if let thePort = model?.portIMAP {
   22.28 +            portValue.text = String(thePort)
   22.29 +        }
   22.30 +        transportSecurity.setTitle(model?.transportIMAP.localizedString(), for: UIControl.State())
   22.31      }
   22.32  
   22.33      @IBAction func alertWithSecurityValues(_ sender: UIButton) {
   22.34 @@ -76,7 +80,7 @@
   22.35                                         comment: "UI alert message for transport protocol"),
   22.36              preferredStyle: .actionSheet)
   22.37          let block: (ConnectionTransport) -> () = { transport in
   22.38 -            self.model.transportIMAP = transport
   22.39 +            self.model?.transportIMAP = transport
   22.40              self.updateView()
   22.41          }
   22.42  
   22.43 @@ -98,13 +102,13 @@
   22.44      @IBAction func changePort(_ sender: UITextField) {
   22.45          if let text = portValue.text {
   22.46              if let port = UInt16(text) {
   22.47 -                model.portIMAP = port
   22.48 +                model?.portIMAP = port
   22.49              }
   22.50          }
   22.51      }
   22.52  
   22.53      @IBAction func changeServer(_ sender: UITextField) {
   22.54 -        model.serverIMAP = serverValue.text!
   22.55 +        model?.serverIMAP = serverValue.text
   22.56      }
   22.57  
   22.58      public func textFieldShouldReturn(_ textfield: UITextField) -> Bool {
   22.59 @@ -129,9 +133,13 @@
   22.60      public override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
   22.61          switch segueIdentifier(for: segue) {
   22.62          case .SMTPSettings:
   22.63 -            let destination = segue.destination as! SMTPSettingsTableViewController
   22.64 -            destination.appConfig = appConfig
   22.65 -            destination.model = model
   22.66 +            if let destination = segue.destination as? SMTPSettingsTableViewController {
   22.67 +                destination.appConfig = appConfig
   22.68 +                destination.model = model
   22.69 +            } else {
   22.70 +                Log.shared.errorAndCrash(
   22.71 +                    "Seque is .SMTPSettings, but controller is not a SMTPSettingsTableViewController")
   22.72 +            }
   22.73              break
   22.74          default:()
   22.75          }
    23.1 --- a/pEpForiOS/UI/ManualLogin/InfoUserSettup/UserInfoTableViewController.swift	Wed May 08 12:31:03 2019 +0200
    23.2 +++ b/pEpForiOS/UI/ManualLogin/InfoUserSettup/UserInfoTableViewController.swift	Fri May 17 14:16:55 2019 +0200
    23.3 @@ -11,8 +11,6 @@
    23.4  import MessageModel
    23.5  
    23.6  class UserInfoTableViewController: BaseTableViewController, TextfieldResponder, UITextFieldDelegate {
    23.7 -    let comp = "UserInfoTableView"
    23.8 -
    23.9      @IBOutlet weak var emailValue: UITextField!
   23.10      @IBOutlet weak var usernameValue: UITextField!
   23.11      @IBOutlet weak var passwordValue: UITextField!
    24.1 --- a/pEpForiOS/UI/ManualLogin/SMTPSetup/SMTPSettingsTableViewController.swift	Wed May 08 12:31:03 2019 +0200
    24.2 +++ b/pEpForiOS/UI/ManualLogin/SMTPSetup/SMTPSettingsTableViewController.swift	Fri May 17 14:16:55 2019 +0200
    24.3 @@ -21,7 +21,9 @@
    24.4      @IBOutlet weak var serverTitle: UILabel!
    24.5      @IBOutlet weak var portTitle: UILabel!
    24.6  
    24.7 -    var model: VerifiableAccountProtocol!
    24.8 +    /// - Note: This VC doesn't have a view model yet, so this is used for the model.
    24.9 +    var model: VerifiableAccountProtocol?
   24.10 +
   24.11      var fields = [UITextField]()
   24.12      var responder = 0
   24.13  
   24.14 @@ -48,7 +50,7 @@
   24.15  
   24.16      public override func viewDidAppear(_ animated: Bool) {
   24.17          super.viewDidAppear(animated)
   24.18 -        firstResponder(model.serverSMTP == nil)
   24.19 +        firstResponder(model?.serverSMTP == nil)
   24.20      }
   24.21  
   24.22      public override func viewDidLayoutSubviews() {
   24.23 @@ -59,9 +61,11 @@
   24.24      // MARK: - Working Bees
   24.25  
   24.26      private func updateView() {
   24.27 -        serverValue.text = model.serverSMTP
   24.28 -        portValue.text = String(model.portSMTP)
   24.29 -        transportSecurity.setTitle(model.transportSMTP.localizedString(), for: UIControl.State())
   24.30 +        serverValue.text = model?.serverSMTP
   24.31 +        if let thePort = model?.portSMTP {
   24.32 +            portValue.text = String(thePort)
   24.33 +        }
   24.34 +        transportSecurity.setTitle(model?.transportSMTP.localizedString(), for: UIControl.State())
   24.35  
   24.36          if isCurrentlyVerifying {
   24.37              activityIndicatorView.startAnimating()
   24.38 @@ -76,8 +80,8 @@
   24.39      /// - Throws: AccountVerificationError
   24.40      private func verifyAccount() throws {
   24.41          isCurrentlyVerifying =  true
   24.42 -        model.verifiableAccountDelegate = self
   24.43 -        try model.verify()
   24.44 +        model?.verifiableAccountDelegate = self
   24.45 +        try model?.verify()
   24.46      }
   24.47  
   24.48      private func informUser(about error: Error, title: String) {
   24.49 @@ -107,7 +111,7 @@
   24.50                                         comment: "UI alert message for transport protocol"),
   24.51              preferredStyle: .actionSheet)
   24.52          let block: (ConnectionTransport) -> () = { transport in
   24.53 -            self.model.transportSMTP = transport
   24.54 +            self.model?.transportSMTP = transport
   24.55              self.updateView()
   24.56          }
   24.57  
   24.58 @@ -127,13 +131,13 @@
   24.59      }
   24.60  
   24.61      @IBAction func changeServer(_ sender: UITextField) {
   24.62 -        model.serverSMTP = sender.text
   24.63 +        model?.serverSMTP = sender.text
   24.64      }
   24.65  
   24.66      @IBAction func changePort(_ sender: UITextField) {
   24.67          if let text = portValue.text {
   24.68              if let port = UInt16(text) {
   24.69 -                model.portSMTP = port
   24.70 +                model?.portSMTP = port
   24.71              }
   24.72          }
   24.73      }
   24.74 @@ -215,19 +219,37 @@
   24.75      func didEndVerification(result: Result<Void, Error>) {
   24.76          switch result {
   24.77          case .success(()):
   24.78 -                MessageModelUtil.performAndWait { [weak self] in
   24.79 -                    do {
   24.80 -                        try self?.model.save()
   24.81 -                    } catch {
   24.82 -                        Log.shared.errorAndCrash("%@", error.localizedDescription)
   24.83 -                    }
   24.84 +            MessageModelUtil.performAndWait { [weak self] in
   24.85 +                // Note: Currently, there is no way for the VC to disappear
   24.86 +                // before the verification has happened.
   24.87 +                guard let theSelf = self else {
   24.88 +                    Log.shared.lostMySelf()
   24.89 +                    return
   24.90                  }
   24.91 -                GCD.onMain() {
   24.92 -                    self.performSegue(withIdentifier: .backToEmailListSegue, sender: self)
   24.93 +
   24.94 +                do {
   24.95 +                    try theSelf.model?.save()
   24.96 +                } catch {
   24.97 +                    Log.shared.errorAndCrash("%@", error.localizedDescription)
   24.98 +                }
   24.99 +            }
  24.100 +            GCD.onMain() {  [weak self] in
  24.101 +                // Note: Currently, there is no way for the VC to disappear
  24.102 +                // before the verification has happened.
  24.103 +                guard let theSelf = self else {
  24.104 +                    Log.shared.lostMySelf()
  24.105 +                    return
  24.106 +                }
  24.107 +
  24.108 +                theSelf.isCurrentlyVerifying = false
  24.109 +                theSelf.performSegue(withIdentifier: .backToEmailListSegue, sender: theSelf)
  24.110              }
  24.111          case .failure(let error):
  24.112 -            GCD.onMain() {
  24.113 -                UIUtils.show(error: error, inViewController: self)
  24.114 +            GCD.onMain() { [weak self] in
  24.115 +                if let theSelf = self {
  24.116 +                    theSelf.isCurrentlyVerifying = false
  24.117 +                    UIUtils.show(error: error, inViewController: theSelf)
  24.118 +                }
  24.119              }
  24.120          }
  24.121      }
    25.1 --- a/pEpForiOS/UI/Settings/Setting/AccountSettings/AccountSettingsTableViewController.swift	Wed May 08 12:31:03 2019 +0200
    25.2 +++ b/pEpForiOS/UI/Settings/Setting/AccountSettings/AccountSettingsTableViewController.swift	Fri May 17 14:16:55 2019 +0200
    25.3 @@ -27,6 +27,9 @@
    25.4      @IBOutlet weak var passwordTableViewCell: UITableViewCell!
    25.5      @IBOutlet weak var oauth2TableViewCell: UITableViewCell!
    25.6      @IBOutlet weak var oauth2ActivityIndicator: UIActivityIndicatorView!
    25.7 +    @IBOutlet weak var doneButton: UIBarButtonItem!
    25.8 +
    25.9 +
   25.10      private let spinner: UIActivityIndicatorView = {
   25.11          let createe = UIActivityIndicatorView()
   25.12          createe.hidesWhenStopped = true
   25.13 @@ -48,7 +51,7 @@
   25.14       should trigger the reauthorization.
   25.15       */
   25.16      var oauth2ReauthIndexPath: IndexPath?
   25.17 -    
   25.18 +
   25.19       override func viewDidLoad() {
   25.20          super.viewDidLoad()
   25.21          configureView()
   25.22 @@ -245,7 +248,7 @@
   25.23                  password = nil
   25.24              }
   25.25  
   25.26 -            showSpinner()
   25.27 +            showSpinnerAndDisableUI()
   25.28              viewModel?.update(loginName: validated.loginName, name: validated.accountName,
   25.29                                password: password, imap: imap, smtp: smtp)
   25.30  
   25.31 @@ -305,10 +308,9 @@
   25.32  // MARK: - AccountVerificationResultDelegate
   25.33  
   25.34  extension AccountSettingsTableViewController: AccountVerificationResultDelegate {
   25.35 -    func didVerify(result: AccountVerificationResult,
   25.36 -                   accountInput: VerifiableAccountProtocol?) {
   25.37 +    func didVerify(result: AccountVerificationResult) {
   25.38          GCD.onMain() {
   25.39 -            self.hideSpinner()
   25.40 +            self.hideSpinnerAndEnableUI()
   25.41              switch result {
   25.42              case .ok:
   25.43                  self.navigationController?.popViewController(animated: true)
   25.44 @@ -346,7 +348,11 @@
   25.45  // MARK: - SPINNER
   25.46  
   25.47  extension AccountSettingsTableViewController {
   25.48 -    private func showSpinner() {
   25.49 +    /// Shows the spinner and disables UI parts that could lead to
   25.50 +    /// launching another verification while one is already in process.
   25.51 +    private func showSpinnerAndDisableUI() {
   25.52 +        doneButton.isEnabled = false
   25.53 +
   25.54          spinner.center =
   25.55              CGPoint(x: tableView.frame.width / 2,
   25.56                      y:
   25.57 @@ -357,7 +363,9 @@
   25.58          spinner.startAnimating()
   25.59      }
   25.60  
   25.61 -    private func hideSpinner() {
   25.62 +    /// Hides the spinner and enables all UI elements again.
   25.63 +    private func hideSpinnerAndEnableUI() {
   25.64 +        doneButton.isEnabled = true
   25.65          tableView.isUserInteractionEnabled = true
   25.66          spinner.stopAnimating()
   25.67      }
    26.1 --- a/pEpForiOS/UI/Settings/Setting/AccountSettings/ViewModel/AccountSettingsViewModel.swift	Wed May 08 12:31:03 2019 +0200
    26.2 +++ b/pEpForiOS/UI/Settings/Setting/AccountSettings/ViewModel/AccountSettingsViewModel.swift	Fri May 17 14:16:55 2019 +0200
    26.3 @@ -44,6 +44,10 @@
    26.4      public let svm = SecurityViewModel()
    26.5      public let isOAuth2: Bool
    26.6  
    26.7 +    /// Holding both the data of the current account in verification,
    26.8 +    /// and also the implementation of the verification.
    26.9 +    public var verifiableAccount: VerifiableAccountProtocol?
   26.10 +
   26.11      public init(account: Account) {
   26.12          // We are using a copy of the data here.
   26.13          // The outside world must not know changed settings until they have been verified.
   26.14 @@ -52,7 +56,18 @@
   26.15          self.loginName = account.server(with: .imap)?.credentials.loginName ?? ""
   26.16          self.name = account.user.userName ?? ""
   26.17  
   26.18 +        if let server = account.imapServer {
   26.19 +            self.originalPassword = server.credentials.password
   26.20 +            self.imapServer = ServerViewModel(
   26.21 +                address: server.address,
   26.22 +                port: "\(server.port)",
   26.23 +                transport: server.transport?.asString())
   26.24 +        } else {
   26.25 +            self.imapServer = ServerViewModel()
   26.26 +        }
   26.27 +
   26.28          if let server = account.smtpServer {
   26.29 +            self.originalPassword = self.originalPassword ?? server.credentials.password
   26.30              self.smtpServer = ServerViewModel(
   26.31                  address: server.address,
   26.32                  port: "\(server.port)",
   26.33 @@ -61,13 +76,15 @@
   26.34              self.smtpServer = ServerViewModel()
   26.35          }
   26.36  
   26.37 -        if let server = account.imapServer {
   26.38 -            self.imapServer = ServerViewModel(
   26.39 -                address: server.address,
   26.40 -                port: "\(server.port)",
   26.41 -                transport: server.transport?.asString())
   26.42 -        } else {
   26.43 -            self.imapServer = ServerViewModel()
   26.44 +        if isOAuth2 {
   26.45 +            if let payload = account.imapServer?.credentials.password ??
   26.46 +                account.smtpServer?.credentials.password,
   26.47 +                let token = OAuth2AccessToken.from(base64Encoded: payload)
   26.48 +                    as? OAuth2AccessTokenProtocol {
   26.49 +                self.accessToken = token
   26.50 +            } else {
   26.51 +                Log.shared.errorAndCrash("Supposed to do OAUTH2, but no existing token")
   26.52 +            }
   26.53          }
   26.54      }
   26.55  
   26.56 @@ -84,12 +101,18 @@
   26.57  
   26.58      weak var delegate: AccountVerificationResultDelegate?
   26.59  
   26.60 -    /// Holding both the data of the current account in verification,
   26.61 -    /// and also the implementation of the verification.
   26.62 -    private var verifiableAccount: VerifiableAccountProtocol?
   26.63 +    /// If the credentials have either an IMAP or SMTP password,
   26.64 +    /// it gets stored here.
   26.65 +    private var originalPassword: String?
   26.66  
   26.67 -    // Currently we assume imap and smtp servers exist already (update).
   26.68 -    // If we run into problems here modify to updateOrCreate.
   26.69 +    /// If there was OAUTH2 for this account, here is a current token.
   26.70 +    /// This trumps both the `originalPassword` and a password given by the user
   26.71 +    /// via the UI.
   26.72 +    /// - Note: For logins that require it, there must be an up-to-date token
   26.73 +    ///         for the verification be able to succeed.
   26.74 +    ///         It is extracted from the existing server credentials on `init`.
   26.75 +    private var accessToken: OAuth2AccessTokenProtocol?
   26.76 +
   26.77      func update(loginName: String, name: String, password: String? = nil, imap: ServerViewModel,
   26.78                  smtp: ServerViewModel) {
   26.79          var theVerifier = verifiableAccount ?? VerifiableAccount()
   26.80 @@ -98,15 +121,23 @@
   26.81          theVerifier.address = email
   26.82          theVerifier.userName = name
   26.83  
   26.84 -        // TODO: How to handle if the password got changed or not?
   26.85 -        theVerifier.password = password
   26.86 -
   26.87          if loginName != email {
   26.88              theVerifier.loginName = loginName
   26.89          }
   26.90  
   26.91          if isOAuth2 {
   26.92 -            // TODO: Set correct auth method, etc.
   26.93 +            if self.accessToken == nil {
   26.94 +                Log.shared.errorAndCrash("Have to do OAUTH2, but lacking current token")
   26.95 +            }
   26.96 +            theVerifier.authMethod = .saslXoauth2
   26.97 +            theVerifier.accessToken = accessToken
   26.98 +            // OAUTH2 trumps any password
   26.99 +            theVerifier.password = nil
  26.100 +        } else {
  26.101 +            theVerifier.password = originalPassword
  26.102 +            if password != nil {
  26.103 +                theVerifier.password = password
  26.104 +            }
  26.105          }
  26.106  
  26.107          // IMAP
  26.108 @@ -132,7 +163,7 @@
  26.109          do {
  26.110              try theVerifier.verify()
  26.111          } catch {
  26.112 -            delegate?.didVerify(result: .noImapConnectData, accountInput: theVerifier)
  26.113 +            delegate?.didVerify(result: .noImapConnectData)
  26.114          }
  26.115      }
  26.116  
  26.117 @@ -175,37 +206,7 @@
  26.118      }
  26.119  
  26.120      func updateToken(accessToken: OAuth2AccessTokenProtocol) {
  26.121 -        // TODO: What to do here? When does this get called?
  26.122 -        /*
  26.123 -        guard let imapServer = account.imapServer,
  26.124 -            let smtpServer = account.smtpServer else {
  26.125 -                return
  26.126 -        }
  26.127 -        let password = accessToken.persistBase64Encoded()
  26.128 -        imapServer.credentials.password = password
  26.129 -        smtpServer.credentials.password = password
  26.130 -         */
  26.131 -    }
  26.132 -}
  26.133 -
  26.134 -// MARK: - AccountVerificationServiceDelegate
  26.135 -
  26.136 -extension AccountSettingsViewModel: AccountVerificationServiceDelegate {
  26.137 -    public func verified(account: Account,
  26.138 -                  service: AccountVerificationServiceProtocol,
  26.139 -                  result: AccountVerificationResult) {
  26.140 -        if result == .ok {
  26.141 -            MessageModelUtil.performAndWait {
  26.142 -                account.save()
  26.143 -            }
  26.144 -        }
  26.145 -        GCD.onMainWait { [weak self] in
  26.146 -            guard let me = self else {
  26.147 -                Log.shared.errorAndCrash("Lost MySelf")
  26.148 -                return
  26.149 -            }
  26.150 -            me.delegate?.didVerify(result: result, accountInput: nil)
  26.151 -        }
  26.152 +        self.accessToken = accessToken
  26.153      }
  26.154  }
  26.155  
  26.156 @@ -217,16 +218,17 @@
  26.157          case .success(()):
  26.158              do {
  26.159                  try verifiableAccount?.save()
  26.160 +                delegate?.didVerify(result: .ok)
  26.161              } catch {
  26.162                  Log.shared.errorAndCrash("%@", error.localizedDescription)
  26.163              }
  26.164          case .failure(let error):
  26.165              if let imapError = error as? ImapSyncError {
  26.166                  delegate?.didVerify(
  26.167 -                    result: .imapError(imapError), accountInput: verifiableAccount)
  26.168 +                    result: .imapError(imapError))
  26.169              } else if let smtpError = error as? SmtpSendError {
  26.170                  delegate?.didVerify(
  26.171 -                    result: .smtpError(smtpError), accountInput: verifiableAccount)
  26.172 +                    result: .smtpError(smtpError))
  26.173              } else {
  26.174                  Log.shared.errorAndCrash("%@", error.localizedDescription)
  26.175              }
    27.1 --- a/pEpForiOS/UI/Settings/Setting/AccountSettings/ViewModel/AccountVerificationResultDelegate.swift	Wed May 08 12:31:03 2019 +0200
    27.2 +++ b/pEpForiOS/UI/Settings/Setting/AccountSettings/ViewModel/AccountVerificationResultDelegate.swift	Fri May 17 14:16:55 2019 +0200
    27.3 @@ -11,5 +11,5 @@
    27.4  import MessageModel
    27.5  
    27.6  protocol AccountVerificationResultDelegate: class {
    27.7 -    func didVerify(result: AccountVerificationResult, accountInput: VerifiableAccountProtocol?)
    27.8 +    func didVerify(result: AccountVerificationResult)
    27.9  }
    28.1 --- a/pEpForiOS/Util/Constants.swift	Wed May 08 12:31:03 2019 +0200
    28.2 +++ b/pEpForiOS/Util/Constants.swift	Fri May 17 14:16:55 2019 +0200
    28.3 @@ -8,12 +8,8 @@
    28.4  
    28.5  import pEpIOSToolbox
    28.6  
    28.7 -extension Constants {
    28.8 -    /** Settings key for storing the email of the last used account */
    28.9 -    static let kSettingLastAccountEmail = "kSettingLastAccountEmail"
   28.10 -
   28.11 -    static let defaultFileName = NSLocalizedString("unnamed",
   28.12 -                                                   comment:
   28.13 +struct Constants {
   28.14 +    static let defaultFileName = NSLocalizedString("unnamed", comment:
   28.15          "file name used for unnamed attachments")
   28.16  
   28.17      /// Storyboard ID to instantiate ComposeViewController
    29.1 --- a/pEpForiOS/Util/Extensions/NSAttributedString+pEp.swift	Wed May 08 12:31:03 2019 +0200
    29.2 +++ b/pEpForiOS/Util/Extensions/NSAttributedString+pEp.swift	Fri May 17 14:16:55 2019 +0200
    29.3 @@ -13,7 +13,7 @@
    29.4  class ToMarkdownDelegate: NSAttributedStringParsingDelegate {
    29.5      var attachments = [Attachment]()
    29.6  
    29.7 -    private let mimeUtil = MimeTypeUtil()
    29.8 +    private lazy var mimeUtils = MimeTypeUtils()
    29.9  
   29.10      func stringFor(attachment: NSTextAttachment) -> String? {
   29.11          if let textAttachment = attachment as? TextAttachment,
   29.12 @@ -22,7 +22,7 @@
   29.13              let count = attachments.count
   29.14  
   29.15              let theID = MessageID.generateUUID()
   29.16 -            let theExt = mimeUtil?.fileExtension(mimeType: theAttachment.mimeType) ?? "jpg"
   29.17 +            let theExt = mimeUtils?.fileExtension(fromMimeType: theAttachment.mimeType) ?? "jpg"
   29.18              let cidBase = "attached-inline-image-\(count)-\(theExt)-\(theID)"
   29.19              let cidSrc = "cid:\(cidBase)"
   29.20              let cidUrl = "cid://\(cidBase)"
   29.21 @@ -38,10 +38,6 @@
   29.22          }
   29.23          return nil
   29.24      }
   29.25 -
   29.26 -    func stringFor(string: String) -> String? {
   29.27 -        return string
   29.28 -    }
   29.29  }
   29.30  
   29.31  extension NSAttributedString {
    30.1 --- a/pEpForiOS/Util/Extensions/URL+MIME.swift	Wed May 08 12:31:03 2019 +0200
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,17 +0,0 @@
    30.4 -//
    30.5 -//  URL+MIME.swift
    30.6 -//  pEp
    30.7 -//
    30.8 -//  Created by Andreas Buff on 24.11.17.
    30.9 -//  Copyright © 2017 p≡p Security S.A. All rights reserved.
   30.10 -//
   30.11 -
   30.12 -import Foundation
   30.13 -
   30.14 -import MessageModel
   30.15 -
   30.16 -extension URL {
   30.17 -    public func mimeType() -> String? {
   30.18 -        return MimeTypeUtil()?.mimeType(fileExtension: self.pathExtension)
   30.19 -    }
   30.20 -}
    31.1 --- a/pEpForiOS/Util/jsonMimeType.txt	Wed May 08 12:31:03 2019 +0200
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,855 +0,0 @@
    31.4 -{
    31.5 -"mimeType" : {
    31.6 -"" : "DEFAULT_ATTACHMENT_MIME_TYPE" ,
    31.7 -"k9s" : "K9_SETTINGS_MIME_TYPE",
    31.8 -"txt" : "text/plain",
    31.9 -"123" : "application/vnd.lotus-1-2-3",
   31.10 -"323" : "text/h323",
   31.11 -"3dml" : "text/vnd.in3d.3dml",
   31.12 -"3g2" : "video/3gpp2",
   31.13 -"3gp" : "video/3gpp",
   31.14 -"aab" : "application/x-authorware-bin",
   31.15 -"aac" : "audio/x-aac",
   31.16 -"aam" : "application/x-authorware-map",
   31.17 -"a" : "application/octet-stream",
   31.18 -"aas" : "application/x-authorware-seg",
   31.19 -"abw" : "application/x-abiword",
   31.20 -"acc" : "application/vnd.americandynamics.acc",
   31.21 -"ace" : "application/x-ace-compressed",
   31.22 -"acu" : "application/vnd.acucobol",
   31.23 -"acutc" : "application/vnd.acucorp",
   31.24 -"acx" : "application/internet-property-stream",
   31.25 -"adp" : "audio/adpcm",
   31.26 -"aep" : "application/vnd.audiograph",
   31.27 -"afm" : "application/x-font-type1",
   31.28 -"afp" : "application/vnd.ibm.modcap",
   31.29 -"ai" : "application/postscript",
   31.30 -"aif" : "audio/x-aiff",
   31.31 -"aifc" : "audio/x-aiff",
   31.32 -"aiff" : "audio/x-aiff",
   31.33 -"air" : "application/vnd.adobe.air-application-installer-package+zip",
   31.34 -"ami" : "application/vnd.amiga.ami",
   31.35 -"apk" : "application/vnd.android.package-archive",
   31.36 -"application" : "application/x-ms-application",
   31.37 -"apr" : "application/vnd.lotus-approach",
   31.38 -"asc" : "application/pgp-signature",
   31.39 -"asf" : "video/x-ms-asf",
   31.40 -"asm" : "text/x-asm",
   31.41 -"aso" : "application/vnd.accpac.simply.aso",
   31.42 -"asr" : "video/x-ms-asf",
   31.43 -"asx" : "video/x-ms-asf",
   31.44 -"atc" : "application/vnd.acucorp",
   31.45 -"atom" : "application/atom+xml",
   31.46 -"atomcat" : "application/atomcat+xml",
   31.47 -"atomsvc" : "application/atomsvc+xml",
   31.48 -"atx" : "application/vnd.antix.game-component",
   31.49 -"au" : "audio/basic",
   31.50 -"avi" : "video/x-msvideo",
   31.51 -"aw" : "application/applixware",
   31.52 -"axs" : "application/olescript",
   31.53 -"azf" : "application/vnd.airzip.filesecure.azf",
   31.54 -"azs" : "application/vnd.airzip.filesecure.azs",
   31.55 -"azw" : "application/vnd.amazon.ebook",
   31.56 -"bas" : "text/plain",
   31.57 -"bat" : "application/x-msdownload",
   31.58 -"bcpio" : "application/x-bcpio",
   31.59 -"bdf" : "application/x-font-bdf",
   31.60 -"bdm" : "application/vnd.syncml.dm+wbxml",
   31.61 -"bh2" : "application/vnd.fujitsu.oasysprs",
   31.62 -"bin" : "application/octet-stream",
   31.63 -"bmi" : "application/vnd.bmi",
   31.64 -"bmp" : "image/bmp",
   31.65 -"book" : "application/vnd.framemaker",
   31.66 -"box" : "application/vnd.previewsystems.box",
   31.67 -"boz" : "application/x-bzip2",
   31.68 -"bpk" : "application/octet-stream",
   31.69 -"btif" : "image/prs.btif",
   31.70 -"bz2" : "application/x-bzip2",
   31.71 -"bz" : "application/x-bzip",
   31.72 -"c4d" : "application/vnd.clonk.c4group",
   31.73 -"c4f" : "application/vnd.clonk.c4group",
   31.74 -"c4g" : "application/vnd.clonk.c4group",
   31.75 -"c4p" : "application/vnd.clonk.c4group",
   31.76 -"c4u" : "application/vnd.clonk.c4group",
   31.77 -"cab" : "application/vnd.ms-cab-compressed",
   31.78 -"car" : "application/vnd.curl.car",
   31.79 -"cat" : "application/vnd.ms-pki.seccat",
   31.80 -"cct" : "application/x-director",
   31.81 -"cc" : "text/x-c",
   31.82 -"ccxml" : "application/ccxml+xml",
   31.83 -"cdbcmsg" : "application/vnd.contact.cmsg",
   31.84 -"cdf" : "application/x-cdf",
   31.85 -"cdkey" : "application/vnd.mediastation.cdkey",
   31.86 -"cdx" : "chemical/x-cdx",
   31.87 -"cdxml" : "application/vnd.chemdraw+xml",
   31.88 -"cdy" : "application/vnd.cinderella",
   31.89 -"cer" : "application/x-x509-ca-cert",
   31.90 -"cgm" : "image/cgm",
   31.91 -"chat" : "application/x-chat",
   31.92 -"chm" : "application/vnd.ms-htmlhelp",
   31.93 -"chrt" : "application/vnd.kde.kchart",
   31.94 -"cif" : "chemical/x-cif",
   31.95 -"cii" : "application/vnd.anser-web-certificate-issue-initiation",
   31.96 -"cla" : "application/vnd.claymore",
   31.97 -"class" : "application/java-vm",
   31.98 -"clkk" : "application/vnd.crick.clicker.keyboard",
   31.99 -"clkp" : "application/vnd.crick.clicker.palette",
  31.100 -"clkt" : "application/vnd.crick.clicker.template",
  31.101 -"clkw" : "application/vnd.crick.clicker.wordbank",
  31.102 -"clkx" : "application/vnd.crick.clicker",
  31.103 -"clp" : "application/x-msclip",
  31.104 -"cmc" : "application/vnd.cosmocaller",
  31.105 -"cmdf" : "chemical/x-cmdf",
  31.106 -"cml" : "chemical/x-cml",
  31.107 -"cmp" : "application/vnd.yellowriver-custom-menu",
  31.108 -"cmx" : "image/x-cmx",
  31.109 -"cod" : "application/vnd.rim.cod",
  31.110 -"com" : "application/x-msdownload",
  31.111 -"conf" : "text/plain",
  31.112 -"cpio" : "application/x-cpio",
  31.113 -"cpp" : "text/x-c",
  31.114 -"cpt" : "application/mac-compactpro",
  31.115 -"crd" : "application/x-mscardfile",
  31.116 -"crl" : "application/pkix-crl",
  31.117 -"crt" : "application/x-x509-ca-cert",
  31.118 -"csh" : "application/x-csh",
  31.119 -"csml" : "chemical/x-csml",
  31.120 -"csp" : "application/vnd.commonspace",
  31.121 -"css" : "text/css",
  31.122 -"cst" : "application/x-director",
  31.123 -"csv" : "text/csv",
  31.124 -"c" : "text/plain",
  31.125 -"cu" : "application/cu-seeme",
  31.126 -"curl" : "text/vnd.curl",
  31.127 -"cww" : "application/prs.cww",
  31.128 -"cxt" : "application/x-director",
  31.129 -"cxx" : "text/x-c",
  31.130 -"daf" : "application/vnd.mobius.daf",
  31.131 -"dataless" : "application/vnd.fdsn.seed",
  31.132 -"davmount" : "application/davmount+xml",
  31.133 -"dcr" : "application/x-director",
  31.134 -"dcurl" : "text/vnd.curl.dcurl",
  31.135 -"dd2" : "application/vnd.oma.dd2+xml",
  31.136 -"ddd" : "application/vnd.fujixerox.ddd",
  31.137 -"deb" : "application/x-debian-package",
  31.138 -"def" : "text/plain",
  31.139 -"deploy" : "application/octet-stream",
  31.140 -"der" : "application/x-x509-ca-cert",
  31.141 -"dfac" : "application/vnd.dreamfactory",
  31.142 -"dic" : "text/x-c",
  31.143 -"diff" : "text/plain",
  31.144 -"dir" : "application/x-director",
  31.145 -"dis" : "application/vnd.mobius.dis",
  31.146 -"dist" : "application/octet-stream",
  31.147 -"distz" : "application/octet-stream",
  31.148 -"djv" : "image/vnd.djvu",
  31.149 -"djvu" : "image/vnd.djvu",
  31.150 -"dll" : "application/x-msdownload",
  31.151 -"dmg" : "application/octet-stream",
  31.152 -"dms" : "application/octet-stream",
  31.153 -"dna" : "application/vnd.dna",
  31.154 -"doc" : "application/msword",
  31.155 -"docm" : "application/vnd.ms-word.document.macroenabled.12",
  31.156 -"docx" : "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  31.157 -"dot" : "application/msword",
  31.158 -"dotm" : "application/vnd.ms-word.template.macroenabled.12",
  31.159 -"dotx" : "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
  31.160 -"dp" : "application/vnd.osgi.dp",
  31.161 -"dpg" : "application/vnd.dpgraph",
  31.162 -"dsc" : "text/prs.lines.tag",
  31.163 -"dtb" : "application/x-dtbook+xml",
  31.164 -"dtd" : "application/xml-dtd",
  31.165 -"dts" : "audio/vnd.dts",
  31.166 -"dtshd" : "audio/vnd.dts.hd",
  31.167 -"dump" : "application/octet-stream",
  31.168 -"dvi" : "application/x-dvi",
  31.169 -"dwf" : "model/vnd.dwf",
  31.170 -"dwg" : "image/vnd.dwg",
  31.171 -"dxf" : "image/vnd.dxf",
  31.172 -"dxp" : "application/vnd.spotfire.dxp",
  31.173 -"dxr" : "application/x-director",
  31.174 -"ecelp4800" : "audio/vnd.nuera.ecelp4800",
  31.175 -"ecelp7470" : "audio/vnd.nuera.ecelp7470",
  31.176 -"ecelp9600" : "audio/vnd.nuera.ecelp9600",
  31.177 -"ecma" : "application/ecmascript",
  31.178 -"edm" : "application/vnd.novadigm.edm",
  31.179 -"edx" : "application/vnd.novadigm.edx",
  31.180 -"efif" : "application/vnd.picsel",
  31.181 -"ei6" : "application/vnd.pg.osasli",
  31.182 -"elc" : "application/octet-stream",
  31.183 -"eml" : "message/rfc822",
  31.184 -"emma" : "application/emma+xml",
  31.185 -"eol" : "audio/vnd.digital-winds",
  31.186 -"eot" : "application/vnd.ms-fontobject",
  31.187 -"eps" : "application/postscript",
  31.188 -"epub" : "application/epub+zip",
  31.189 -"es3" : "application/vnd.eszigno3+xml",
  31.190 -"esf" : "application/vnd.epson.esf",
  31.191 -"espass" : "application/vnd.espass-espass+zip",
  31.192 -"et3" : "application/vnd.eszigno3+xml",
  31.193 -"etx" : "text/x-setext",
  31.194 -"evy" : "application/envoy",
  31.195 -"exe" : "application/octet-stream",
  31.196 -"ext" : "application/vnd.novadigm.ext",
  31.197 -"ez2" : "application/vnd.ezpix-album",
  31.198 -"ez3" : "application/vnd.ezpix-package",
  31.199 -"ez" : "application/andrew-inset",
  31.200 -"f4v" : "video/x-f4v",
  31.201 -"f77" : "text/x-fortran",
  31.202 -"f90" : "text/x-fortran",
  31.203 -"fbs" : "image/vnd.fastbidsheet",
  31.204 -"fdf" : "application/vnd.fdf",
  31.205 -"fe_launch" : "application/vnd.denovo.fcselayout-link",
  31.206 -"fg5" : "application/vnd.fujitsu.oasysgp",
  31.207 -"fgd" : "application/x-director",
  31.208 -"fh4" : "image/x-freehand",
  31.209 -"fh5" : "image/x-freehand",
  31.210 -"fh7" : "image/x-freehand",
  31.211 -"fhc" : "image/x-freehand",
  31.212 -"fh" : "image/x-freehand",
  31.213 -"fif" : "application/fractals",
  31.214 -"fig" : "application/x-xfig",
  31.215 -"fli" : "video/x-fli",
  31.216 -"flo" : "application/vnd.micrografx.flo",
  31.217 -"flr" : "x-world/x-vrml",
  31.218 -"flv" : "video/x-flv",
  31.219 -"flw" : "application/vnd.kde.kivio",
  31.220 -"flx" : "text/vnd.fmi.flexstor",
  31.221 -"fly" : "text/vnd.fly",
  31.222 -"fm" : "application/vnd.framemaker",
  31.223 -"fnc" : "application/vnd.frogans.fnc",
  31.224 -"for" : "text/x-fortran",
  31.225 -"fpx" : "image/vnd.fpx",
  31.226 -"frame" : "application/vnd.framemaker",
  31.227 -"fsc" : "application/vnd.fsc.weblaunch",
  31.228 -"fst" : "image/vnd.fst",
  31.229 -"ftc" : "application/vnd.fluxtime.clip",
  31.230 -"f" : "text/x-fortran",
  31.231 -"fti" : "application/vnd.anser-web-funds-transfer-initiation",
  31.232 -"fvt" : "video/vnd.fvt",
  31.233 -"fzs" : "application/vnd.fuzzysheet",
  31.234 -"g3" : "image/g3fax",
  31.235 -"gac" : "application/vnd.groove-account",
  31.236 -"gdl" : "model/vnd.gdl",
  31.237 -"geo" : "application/vnd.dynageo",
  31.238 -"gex" : "application/vnd.geometry-explorer",
  31.239 -"ggb" : "application/vnd.geogebra.file",
  31.240 -"ggt" : "application/vnd.geogebra.tool",
  31.241 -"ghf" : "application/vnd.groove-help",
  31.242 -"gif" : "image/gif",
  31.243 -"gim" : "application/vnd.groove-identity-message",
  31.244 -"gmx" : "application/vnd.gmx",
  31.245 -"gnumeric" : "application/x-gnumeric",
  31.246 -"gph" : "application/vnd.flographit",
  31.247 -"gqf" : "application/vnd.grafeq",
  31.248 -"gqs" : "application/vnd.grafeq",
  31.249 -"gram" : "application/srgs",
  31.250 -"gre" : "application/vnd.geometry-explorer",
  31.251 -"grv" : "application/vnd.groove-injector",
  31.252 -"grxml" : "application/srgs+xml",
  31.253 -"gsf" : "application/x-font-ghostscript",
  31.254 -"gtar" : "application/x-gtar",
  31.255 -"gtm" : "application/vnd.groove-tool-message",
  31.256 -"gtw" : "model/vnd.gtw",
  31.257 -"gv" : "text/vnd.graphviz",
  31.258 -"gz" : "application/x-gzip",
  31.259 -"h261" : "video/h261",
  31.260 -"h263" : "video/h263",
  31.261 -"h264" : "video/h264",
  31.262 -"hbci" : "application/vnd.hbci",
  31.263 -"hdf" : "application/x-hdf",
  31.264 -"hh" : "text/x-c",
  31.265 -"hlp" : "application/winhlp",
  31.266 -"hpgl" : "application/vnd.hp-hpgl",
  31.267 -"hpid" : "application/vnd.hp-hpid",
  31.268 -"hps" : "application/vnd.hp-hps",
  31.269 -"hqx" : "application/mac-binhex40",
  31.270 -"hta" : "application/hta",
  31.271 -"htc" : "text/x-component",
  31.272 -"h" : "text/plain",
  31.273 -"htke" : "application/vnd.kenameaapp",
  31.274 -"html" : "text/html",
  31.275 -"htm" : "text/html",
  31.276 -"htt" : "text/webviewhtml",
  31.277 -"hvd" : "application/vnd.yamaha.hv-dic",
  31.278 -"hvp" : "application/vnd.yamaha.hv-voice",
  31.279 -"hvs" : "application/vnd.yamaha.hv-script",
  31.280 -"icc" : "application/vnd.iccprofile",
  31.281 -"ice" : "x-conference/x-cooltalk",
  31.282 -"icm" : "application/vnd.iccprofile",
  31.283 -"ico" : "image/x-icon",
  31.284 -"ics" : "text/calendar",
  31.285 -"ief" : "image/ief",
  31.286 -"ifb" : "text/calendar",
  31.287 -"ifm" : "application/vnd.shana.informed.formdata",
  31.288 -"iges" : "model/iges",
  31.289 -"igl" : "application/vnd.igloader",
  31.290 -"igs" : "model/iges",
  31.291 -"igx" : "application/vnd.micrografx.igx",
  31.292 -"iif" : "application/vnd.shana.informed.interchange",
  31.293 -"iii" : "application/x-iphone",
  31.294 -"imp" : "application/vnd.accpac.simply.imp",
  31.295 -"ims" : "application/vnd.ms-ims",
  31.296 -"ins" : "application/x-internet-signup",
  31.297 -"in" : "text/plain",
  31.298 -"ipk" : "application/vnd.shana.informed.package",
  31.299 -"irm" : "application/vnd.ibm.rights-management",
  31.300 -"irp" : "application/vnd.irepository.package+xml",
  31.301 -"iso" : "application/octet-stream",
  31.302 -"isp" : "application/x-internet-signup",
  31.303 -"itp" : "application/vnd.shana.informed.formtemplate",
  31.304 -"ivp" : "application/vnd.immervision-ivp",
  31.305 -"ivu" : "application/vnd.immervision-ivu",
  31.306 -"jad" : "text/vnd.sun.j2me.app-descriptor",
  31.307 -"jam" : "application/vnd.jam",
  31.308 -"jar" : "application/java-archive",
  31.309 -"java" : "text/x-java-source",
  31.310 -"jfif" : "image/pipeg",
  31.311 -"jisp" : "application/vnd.jisp",
  31.312 -"jlt" : "application/vnd.hp-jlyt",
  31.313 -"jnlp" : "application/x-java-jnlp-file",
  31.314 -"joda" : "application/vnd.joost.joda-archive",
  31.315 -"jpeg" : "image/jpeg",
  31.316 -"jpe" : "image/jpeg",
  31.317 -"jpg" : "image/jpeg",
  31.318 -"jpgm" : "video/jpm",
  31.319 -"jpgv" : "video/jpeg",
  31.320 -"jpm" : "video/jpm",
  31.321 -"js" : "application/x-javascript",
  31.322 -"json" : "application/json",
  31.323 -"kar" : "audio/midi",
  31.324 -"karbon" : "application/vnd.kde.karbon",
  31.325 -"kfo" : "application/vnd.kde.kformula",
  31.326 -"kia" : "application/vnd.kidspiration",
  31.327 -"kil" : "application/x-killustrator",
  31.328 -"kml" : "application/vnd.google-earth.kml+xml",
  31.329 -"kmz" : "application/vnd.google-earth.kmz",
  31.330 -"kne" : "application/vnd.kinar",
  31.331 -"knp" : "application/vnd.kinar",
  31.332 -"kon" : "application/vnd.kde.kontour",
  31.333 -"kpr" : "application/vnd.kde.kpresenter",
  31.334 -"kpt" : "application/vnd.kde.kpresenter",
  31.335 -"ksh" : "text/plain",
  31.336 -"ksp" : "application/vnd.kde.kspread",
  31.337 -"ktr" : "application/vnd.kahootz",
  31.338 -"ktz" : "application/vnd.kahootz",
  31.339 -"kwd" : "application/vnd.kde.kword",
  31.340 -"kwt" : "application/vnd.kde.kword",
  31.341 -"latex" : "application/x-latex",
  31.342 -"lbd" : "application/vnd.llamagraphics.life-balance.desktop",
  31.343 -"lbe" : "application/vnd.llamagraphics.life-balance.exchange+xml",
  31.344 -"les" : "application/vnd.hhe.lesson-player",
  31.345 -"lha" : "application/octet-stream",
  31.346 -"link66" : "application/vnd.route66.link66+xml",
  31.347 -"list3820" : "application/vnd.ibm.modcap",
  31.348 -"listafp" : "application/vnd.ibm.modcap",
  31.349 -"list" : "text/plain",
  31.350 -"log" : "text/plain",
  31.351 -"lostxml" : "application/lost+xml",
  31.352 -"lrf" : "application/octet-stream",
  31.353 -"lrm" : "application/vnd.ms-lrm",
  31.354 -"lsf" : "video/x-la-asf",
  31.355 -"lsx" : "video/x-la-asf",
  31.356 -"ltf" : "application/vnd.frogans.ltf",
  31.357 -"lvp" : "audio/vnd.lucent.voice",
  31.358 -"lwp" : "application/vnd.lotus-wordpro",
  31.359 -"lzh" : "application/octet-stream",
  31.360 -"m13" : "application/x-msmediaview",
  31.361 -"m14" : "application/x-msmediaview",
  31.362 -"m1v" : "video/mpeg",
  31.363 -"m2a" : "audio/mpeg",
  31.364 -"m2v" : "video/mpeg",
  31.365 -"m3a" : "audio/mpeg",
  31.366 -"m3u" : "audio/x-mpegurl",
  31.367 -"m4u" : "video/vnd.mpegurl",
  31.368 -"m4v" : "video/x-m4v",
  31.369 -"ma" : "application/mathematica",
  31.370 -"mag" : "application/vnd.ecowin.chart",
  31.371 -"maker" : "application/vnd.framemaker",
  31.372 -"man" : "text/troff",
  31.373 -"mathml" : "application/mathml+xml",
  31.374 -"mb" : "application/mathematica",
  31.375 -"mbk" : "application/vnd.mobius.mbk",
  31.376 -"mbox" : "application/mbox",
  31.377 -"mc1" : "application/vnd.medcalcdata",
  31.378 -"mcd" : "application/vnd.mcd",
  31.379 -"mcurl" : "text/vnd.curl.mcurl",
  31.380 -"mdb" : "application/x-msaccess",
  31.381 -"mdi" : "image/vnd.ms-modi",
  31.382 -"mesh" : "model/mesh",
  31.383 -"me" : "text/troff",
  31.384 -"mfm" : "application/vnd.mfmp",
  31.385 -"mgz" : "application/vnd.proteus.magazine",
  31.386 -"mht" : "message/rfc822",
  31.387 -"mhtml" : "message/rfc822",
  31.388 -"mid" : "audio/midi",
  31.389 -"midi" : "audio/midi",
  31.390 -"mif" : "application/vnd.mif",
  31.391 -"mime" : "message/rfc822",
  31.392 -"mj2" : "video/mj2",
  31.393 -"mjp2" : "video/mj2",
  31.394 -"mlp" : "application/vnd.dolby.mlp",
  31.395 -"mmd" : "application/vnd.chipnuts.karaoke-mmd",
  31.396 -"mmf" : "application/vnd.smaf",
  31.397 -"mmr" : "image/vnd.fujixerox.edmics-mmr",
  31.398 -"mny" : "application/x-msmoney",
  31.399 -"mobi" : "application/x-mobipocket-ebook",
  31.400 -"movie" : "video/x-sgi-movie",
  31.401 -"mov" : "video/quicktime",
  31.402 -"mp2a" : "audio/mpeg",
  31.403 -"mp2" : "video/mpeg",
  31.404 -"mp3" : "audio/mpeg",
  31.405 -"mp4a" : "audio/mp4",
  31.406 -"mp4s" : "application/mp4",
  31.407 -"mp4" : "video/mp4",
  31.408 -"mp4v" : "video/mp4",
  31.409 -"mpa" : "video/mpeg",
  31.410 -"mpc" : "application/vnd.mophun.certificate",
  31.411 -"mpeg" : "video/mpeg",
  31.412 -"mpe" : "video/mpeg",
  31.413 -"mpg4" : "video/mp4",
  31.414 -"mpga" : "audio/mpeg",
  31.415 -"mpg" : "video/mpeg",
  31.416 -"mpkg" : "application/vnd.apple.installer+xml",
  31.417 -"mpm" : "application/vnd.blueice.multipass",
  31.418 -"mpn" : "application/vnd.mophun.application",
  31.419 -"mpp" : "application/vnd.ms-project",
  31.420 -"mpt" : "application/vnd.ms-project",
  31.421 -"mpv2" : "video/mpeg",
  31.422 -"mpy" : "application/vnd.ibm.minipay",
  31.423 -"mqy" : "application/vnd.mobius.mqy",
  31.424 -"mrc" : "application/marc",
  31.425 -"mscml" : "application/mediaservercontrol+xml",
  31.426 -"mseed" : "application/vnd.fdsn.mseed",
  31.427 -"mseq" : "application/vnd.mseq",
  31.428 -"msf" : "application/vnd.epson.msf",
  31.429 -"msh" : "model/mesh",
  31.430 -"msi" : "application/x-msdownload",
  31.431 -"ms" : "text/troff",
  31.432 -"msty" : "application/vnd.muvee.style",
  31.433 -"mts" : "model/vnd.mts",
  31.434 -"mus" : "application/vnd.musician",
  31.435 -"musicxml" : "application/vnd.recordare.musicxml+xml",
  31.436 -"mvb" : "application/x-msmediaview",
  31.437 -"mxf" : "application/mxf",
  31.438 -"mxl" : "application/vnd.recordare.musicxml",
  31.439 -"mxml" : "application/xv+xml",
  31.440 -"mxs" : "application/vnd.triscape.mxs",
  31.441 -"mxu" : "video/vnd.mpegurl",
  31.442 -"nb" : "application/mathematica",
  31.443 -"nc" : "application/x-netcdf",
  31.444 -"ncx" : "application/x-dtbncx+xml",
  31.445 -"n-gage" : "application/vnd.nokia.n-gage.symbian.install",
  31.446 -"ngdat" : "application/vnd.nokia.n-gage.data",
  31.447 -"nlu" : "application/vnd.neurolanguage.nlu",
  31.448 -"nml" : "application/vnd.enliven",
  31.449 -"nnd" : "application/vnd.noblenet-directory",
  31.450 -"nns" : "application/vnd.noblenet-sealer",
  31.451 -"nnw" : "application/vnd.noblenet-web",
  31.452 -"npx" : "image/vnd.net-fpx",
  31.453 -"nsf" : "application/vnd.lotus-notes",
  31.454 -"nws" : "message/rfc822",
  31.455 -"oa2" : "application/vnd.fujitsu.oasys2",
  31.456 -"oa3" : "application/vnd.fujitsu.oasys3",
  31.457 -"o" : "application/octet-stream",
  31.458 -"oas" : "application/vnd.fujitsu.oasys",
  31.459 -"obd" : "application/x-msbinder",
  31.460 -"obj" : "application/octet-stream",
  31.461 -"oda" : "application/oda",
  31.462 -"odb" : "application/vnd.oasis.opendocument.database",
  31.463 -"odc" : "application/vnd.oasis.opendocument.chart",
  31.464 -"odf" : "application/vnd.oasis.opendocument.formula",
  31.465 -"odft" : "application/vnd.oasis.opendocument.formula-template",
  31.466 -"odg" : "application/vnd.oasis.opendocument.graphics",
  31.467 -"odi" : "application/vnd.oasis.opendocument.image",
  31.468 -"odp" : "application/vnd.oasis.opendocument.presentation",
  31.469 -"ods" : "application/vnd.oasis.opendocument.spreadsheet",
  31.470 -"odt" : "application/vnd.oasis.opendocument.text",
  31.471 -"oga" : "audio/ogg",
  31.472 -"ogg" : "audio/ogg",
  31.473 -"ogv" : "video/ogg",
  31.474 -"ogx" : "application/ogg",
  31.475 -"onepkg" : "application/onenote",
  31.476 -"onetmp" : "application/onenote",
  31.477 -"onetoc2" : "application/onenote",
  31.478 -"onetoc" : "application/onenote",
  31.479 -"opf" : "application/oebps-package+xml",
  31.480 -"oprc" : "application/vnd.palm",
  31.481 -"org" : "application/vnd.lotus-organizer",
  31.482 -"osf" : "application/vnd.yamaha.openscoreformat",
  31.483 -"osfpvg" : "application/vnd.yamaha.openscoreformat.osfpvg+xml",
  31.484 -"otc" : "application/vnd.oasis.opendocument.chart-template",
  31.485 -"otf" : "application/x-font-otf",
  31.486 -"otg" : "application/vnd.oasis.opendocument.graphics-template",
  31.487 -"oth" : "application/vnd.oasis.opendocument.text-web",
  31.488 -"oti" : "application/vnd.oasis.opendocument.image-template",
  31.489 -"otm" : "application/vnd.oasis.opendocument.text-master",
  31.490 -"otp" : "application/vnd.oasis.opendocument.presentation-template",
  31.491 -"ots" : "application/vnd.oasis.opendocument.spreadsheet-template",
  31.492 -"ott" : "application/vnd.oasis.opendocument.text-template",
  31.493 -"oxt" : "application/vnd.openofficeorg.extension",
  31.494 -"p10" : "application/pkcs10",
  31.495 -"p12" : "application/x-pkcs12",
  31.496 -"p7b" : "application/x-pkcs7-certificates",
  31.497 -"p7c" : "application/x-pkcs7-mime",
  31.498 -"p7m" : "application/x-pkcs7-mime",
  31.499 -"p7r" : "application/x-pkcs7-certreqresp",
  31.500 -"p7s" : "application/x-pkcs7-signature",
  31.501 -"pas" : "text/x-pascal",
  31.502 -"pbd" : "application/vnd.powerbuilder6",
  31.503 -"pbm" : "image/x-portable-bitmap",
  31.504 -"pcf" : "application/x-font-pcf",
  31.505 -"pcl" : "application/vnd.hp-pcl",
  31.506 -"pclxl" : "application/vnd.hp-pclxl",
  31.507 -"pct" : "image/x-pict",
  31.508 -"pcurl" : "application/vnd.curl.pcurl",
  31.509 -"pcx" : "image/x-pcx",
  31.510 -"pdb" : "application/vnd.palm",
  31.511 -"pdf" : "application/pdf",
  31.512 -"pfa" : "application/x-font-type1",
  31.513 -"pfb" : "application/x-font-type1",
  31.514 -"pfm" : "application/x-font-type1",
  31.515 -"pfr" : "application/font-tdpfr",
  31.516 -"pfx" : "application/x-pkcs12",
  31.517 -"pgm" : "image/x-portable-graymap",
  31.518 -"pgn" : "application/x-chess-pgn",
  31.519 -"pgp" : "application/pgp-encrypted",
  31.520 -"pic" : "image/x-pict",
  31.521 -"pkg" : "application/octet-stream",
  31.522 -"pki" : "application/pkixcmp",
  31.523 -"pkipath" : "application/pkix-pkipath",
  31.524 -"pkpass" : "application/vnd-com.apple.pkpass",
  31.525 -"pko" : "application/ynd.ms-pkipko",
  31.526 -"plb" : "application/vnd.3gpp.pic-bw-large",
  31.527 -"plc" : "application/vnd.mobius.plc",
  31.528 -"plf" : "application/vnd.pocketlearn",
  31.529 -"pls" : "application/pls+xml",
  31.530 -"pl" : "text/plain",
  31.531 -"pma" : "application/x-perfmon",
  31.532 -"pmc" : "application/x-perfmon",
  31.533 -"pml" : "application/x-perfmon",
  31.534 -"pmr" : "application/x-perfmon",
  31.535 -"pmw" : "application/x-perfmon",
  31.536 -"png" : "image/png",
  31.537 -"pnm" : "image/x-portable-anymap",
  31.538 -"portpkg" : "application/vnd.macports.portpkg",
  31.539 -"pot," : "application/vnd.ms-powerpoint",
  31.540 -"pot" : "application/vnd.ms-powerpoint",
  31.541 -"potm" : "application/vnd.ms-powerpoint.template.macroenabled.12",
  31.542 -"potx" : "application/vnd.openxmlformats-officedocument.presentationml.template",
  31.543 -"ppa" : "application/vnd.ms-powerpoint",
  31.544 -"ppam" : "application/vnd.ms-powerpoint.addin.macroenabled.12",
  31.545 -"ppd" : "application/vnd.cups-ppd",
  31.546 -"ppm" : "image/x-portable-pixmap",
  31.547 -"pps" : "application/vnd.ms-powerpoint",
  31.548 -"ppsm" : "application/vnd.ms-powerpoint.slideshow.macroenabled.12",
  31.549 -"ppsx" : "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
  31.550 -"ppt" : "application/vnd.ms-powerpoint",
  31.551 -"pptm" : "application/vnd.ms-powerpoint.presentation.macroenabled.12",
  31.552 -"pptx" : "application/vnd.openxmlformats-officedocument.presentationml.presentation",
  31.553 -"pqa" : "application/vnd.palm",
  31.554 -"prc" : "application/x-mobipocket-ebook",
  31.555 -"pre" : "application/vnd.lotus-freelance",
  31.556 -"prf" : "application/pics-rules",
  31.557 -"ps" : "application/postscript",
  31.558 -"psb" : "application/vnd.3gpp.pic-bw-small",
  31.559 -"psd" : "image/vnd.adobe.photoshop",
  31.560 -"psf" : "application/x-font-linux-psf",
  31.561 -"p" : "text/x-pascal",
  31.562 -"ptid" : "application/vnd.pvi.ptid1",
  31.563 -"pub" : "application/x-mspublisher",
  31.564 -"pvb" : "application/vnd.3gpp.pic-bw-var",
  31.565 -"pwn" : "application/vnd.3m.post-it-notes",
  31.566 -"pwz" : "application/vnd.ms-powerpoint",
  31.567 -"pya" : "audio/vnd.ms-playready.media.pya",
  31.568 -"pyc" : "application/x-python-code",
  31.569 -"pyo" : "application/x-python-code",
  31.570 -"py" : "text/x-python",
  31.571 -"pyv" : "video/vnd.ms-playready.media.pyv",
  31.572 -"qam" : "application/vnd.epson.quickanime",
  31.573 -"qbo" : "application/vnd.intu.qbo",
  31.574 -"qfx" : "application/vnd.intu.qfx",
  31.575 -"qps" : "application/vnd.publishare-delta-tree",
  31.576 -"qt" : "video/quicktime",
  31.577 -"qwd" : "application/vnd.quark.quarkxpress",
  31.578 -"qwt" : "application/vnd.quark.quarkxpress",
  31.579 -"qxb" : "application/vnd.quark.quarkxpress",
  31.580 -"qxd" : "application/vnd.quark.quarkxpress",
  31.581 -"qxl" : "application/vnd.quark.quarkxpress",
  31.582 -"qxt" : "application/vnd.quark.quarkxpress",
  31.583 -"ra" : "audio/x-pn-realaudio",
  31.584 -"ram" : "audio/x-pn-realaudio",
  31.585 -"rar" : "application/x-rar-compressed",
  31.586 -"ras" : "image/x-cmu-raster",
  31.587 -"rcprofile" : "application/vnd.ipunplugged.rcprofile",
  31.588 -"rdf" : "application/rdf+xml",
  31.589 -"rdz" : "application/vnd.data-vision.rdz",
  31.590 -"rep" : "application/vnd.businessobjects",
  31.591 -"res" : "application/x-dtbresource+xml",
  31.592 -"rgb" : "image/x-rgb",
  31.593 -"rif" : "application/reginfo+xml",
  31.594 -"rl" : "application/resource-lists+xml",
  31.595 -"rlc" : "image/vnd.fujixerox.edmics-rlc",
  31.596 -"rld" : "application/resource-lists-diff+xml",
  31.597 -"rm" : "application/vnd.rn-realmedia",
  31.598 -"rmi" : "audio/midi",
  31.599 -"rmp" : "audio/x-pn-realaudio-plugin",
  31.600 -"rms" : "application/vnd.jcp.javame.midlet-rms",
  31.601 -"rnc" : "application/relax-ng-compact-syntax",
  31.602 -"roff" : "text/troff",
  31.603 -"rpm" : "application/x-rpm",
  31.604 -"rpss" : "application/vnd.nokia.radio-presets",
  31.605 -"rpst" : "application/vnd.nokia.radio-preset",
  31.606 -"rq" : "application/sparql-query",
  31.607 -"rs" : "application/rls-services+xml",
  31.608 -"rsd" : "application/rsd+xml",
  31.609 -"rss" : "application/rss+xml",
  31.610 -"rtf" : "application/rtf",
  31.611 -"rtx" : "text/richtext",
  31.612 -"saf" : "application/vnd.yamaha.smaf-audio",
  31.613 -"sbml" : "application/sbml+xml",
  31.614 -"sc" : "application/vnd.ibm.secure-container",
  31.615 -"scd" : "application/x-msschedule",
  31.616 -"scm" : "application/vnd.lotus-screencam",
  31.617 -"scq" : "application/scvp-cv-request",
  31.618 -"scs" : "application/scvp-cv-response",
  31.619 -"sct" : "text/scriptlet",
  31.620 -"scurl" : "text/vnd.curl.scurl",
  31.621 -"sda" : "application/vnd.stardivision.draw",
  31.622 -"sdc" : "application/vnd.stardivision.calc",
  31.623 -"sdd" : "application/vnd.stardivision.impress",
  31.624 -"sdkd" : "application/vnd.solent.sdkm+xml",
  31.625 -"sdkm" : "application/vnd.solent.sdkm+xml",
  31.626 -"sdp" : "application/sdp",
  31.627 -"sdw" : "application/vnd.stardivision.writer",
  31.628 -"see" : "application/vnd.seemail",
  31.629 -"seed" : "application/vnd.fdsn.seed",
  31.630 -"sema" : "application/vnd.sema",
  31.631 -"semd" : "application/vnd.semd",
  31.632 -"semf" : "application/vnd.semf",
  31.633 -"ser" : "application/java-serialized-object",
  31.634 -"setpay" : "application/set-payment-initiation",
  31.635 -"setreg" : "application/set-registration-initiation",
  31.636 -"sfd-hdstx" : "application/vnd.hydrostatix.sof-data",
  31.637 -"sfs" : "application/vnd.spotfire.sfs",
  31.638 -"sgl" : "application/vnd.stardivision.writer-global",
  31.639 -"sgml" : "text/sgml",
  31.640 -"sgm" : "text/sgml",
  31.641 -"sh" : "application/x-sh",
  31.642 -"shar" : "application/x-shar",
  31.643 -"shf" : "application/shf+xml",
  31.644 -"sic" : "application/vnd.wap.sic",
  31.645 -"sig" : "application/pgp-signature",
  31.646 -"silo" : "model/mesh",
  31.647 -"sis" : "application/vnd.symbian.install",
  31.648 -"sisx" : "application/vnd.symbian.install",
  31.649 -"sit" : "application/x-stuffit",
  31.650 -"si" : "text/vnd.wap.si",
  31.651 -"sitx" : "application/x-stuffitx",
  31.652 -"skd" : "application/vnd.koan",
  31.653 -"skm" : "application/vnd.koan",
  31.654 -"skp" : "application/vnd.koan",
  31.655 -"skt" : "application/vnd.koan",
  31.656 -"slc" : "application/vnd.wap.slc",
  31.657 -"sldm" : "application/vnd.ms-powerpoint.slide.macroenabled.12",
  31.658 -"sldx" : "application/vnd.openxmlformats-officedocument.presentationml.slide",
  31.659 -"slt" : "application/vnd.epson.salt",
  31.660 -"sl" : "text/vnd.wap.sl",
  31.661 -"smf" : "application/vnd.stardivision.math",
  31.662 -"smi" : "application/smil+xml",
  31.663 -"smil" : "application/smil+xml",
  31.664 -"snd" : "audio/basic",
  31.665 -"snf" : "application/x-font-snf",
  31.666 -"so" : "application/octet-stream",
  31.667 -"spc" : "application/x-pkcs7-certificates",
  31.668 -"spf" : "application/vnd.yamaha.smaf-phrase",
  31.669 -"spl" : "application/x-futuresplash",
  31.670 -"spot" : "text/vnd.in3d.spot",
  31.671 -"spp" : "application/scvp-vp-response",
  31.672 -"spq" : "application/scvp-vp-request",
  31.673 -"spx" : "audio/ogg",
  31.674 -"src" : "application/x-wais-source",
  31.675 -"srx" : "application/sparql-results+xml",
  31.676 -"sse" : "application/vnd.kodak-descriptor",
  31.677 -"ssf" : "application/vnd.epson.ssf",
  31.678 -"ssml" : "application/ssml+xml",
  31.679 -"sst" : "application/vnd.ms-pkicertstore",
  31.680 -"stc" : "application/vnd.sun.xml.calc.template",
  31.681 -"std" : "application/vnd.sun.xml.draw.template",
  31.682 -"s" : "text/x-asm",
  31.683 -"stf" : "application/vnd.wt.stf",
  31.684 -"sti" : "application/vnd.sun.xml.impress.template",
  31.685 -"stk" : "application/hyperstudio",
  31.686 -"stl" : "application/vnd.ms-pki.stl",
  31.687 -"stm" : "text/html",
  31.688 -"str" : "application/vnd.pg.format",
  31.689 -"stw" : "application/vnd.sun.xml.writer.template",
  31.690 -"sus" : "application/vnd.sus-calendar",
  31.691 -"susp" : "application/vnd.sus-calendar",
  31.692 -"sv4cpio" : "application/x-sv4cpio",
  31.693 -"sv4crc" : "application/x-sv4crc",
  31.694 -"svd" : "application/vnd.svd",
  31.695 -"svg" : "image/svg+xml",
  31.696 -"svgz" : "image/svg+xml",
  31.697 -"swa" : "application/x-director",
  31.698 -"swf" : "application/x-shockwave-flash",
  31.699 -"swi" : "application/vnd.arastra.swi",
  31.700 -"sxc" : "application/vnd.sun.xml.calc",
  31.701 -"sxd" : "application/vnd.sun.xml.draw",
  31.702 -"sxg" : "application/vnd.sun.xml.writer.global",
  31.703 -"sxi" : "application/vnd.sun.xml.impress",
  31.704 -"sxm" : "application/vnd.sun.xml.math",
  31.705 -"sxw" : "application/vnd.sun.xml.writer",
  31.706 -"tao" : "application/vnd.tao.intent-module-archive",
  31.707 -"t" : "application/x-troff",
  31.708 -"tar" : "application/x-tar",
  31.709 -"tcap" : "application/vnd.3gpp2.tcap",
  31.710 -"tcl" : "application/x-tcl",
  31.711 -"teacher" : "application/vnd.smart.teacher",
  31.712 -"tex" : "application/x-tex",
  31.713 -"texi" : "application/x-texinfo",
  31.714 -"texinfo" : "application/x-texinfo",
  31.715 -"text" : "text/plain",
  31.716 -"tfm" : "application/x-tex-tfm",
  31.717 -"tgz" : "application/x-gzip",
  31.718 -"tiff" : "image/tiff",
  31.719 -"tif" : "image/tiff",
  31.720 -"tmo" : "application/vnd.tmobile-livetv",
  31.721 -"torrent" : "application/x-bittorrent",
  31.722 -"tpl" : "application/vnd.groove-tool-template",
  31.723 -"tpt" : "application/vnd.trid.tpt",
  31.724 -"tra" : "application/vnd.trueapp",
  31.725 -"trm" : "application/x-msterminal",
  31.726 -"tr" : "text/troff",
  31.727 -"tsv" : "text/tab-separated-values",
  31.728 -"ttc" : "application/x-font-ttf",
  31.729 -"ttf" : "application/x-font-ttf",
  31.730 -"twd" : "application/vnd.simtech-mindmapper",
  31.731 -"twds" : "application/vnd.simtech-mindmapper",
  31.732 -"txd" : "application/vnd.genomatix.tuxedo",
  31.733 -"txf" : "application/vnd.mobius.txf",
  31.734 -"txt" : "text/plain",
  31.735 -"u32" : "application/x-authorware-bin",
  31.736 -"udeb" : "application/x-debian-package",
  31.737 -"ufd" : "application/vnd.ufdl",
  31.738 -"ufdl" : "application/vnd.ufdl",
  31.739 -"uls" : "text/iuls",
  31.740 -"umj" : "application/vnd.umajin",
  31.741 -"unityweb" : "application/vnd.unity",
  31.742 -"uoml" : "application/vnd.uoml+xml",
  31.743 -"uris" : "text/uri-list",
  31.744 -"uri" : "text/uri-list",
  31.745 -"urls" : "text/uri-list",
  31.746 -"ustar" : "application/x-ustar",
  31.747 -"utz" : "application/vnd.uiq.theme",
  31.748 -"uu" : "text/x-uuencode",
  31.749 -"vcd" : "application/x-cdlink",
  31.750 -"vcf" : "text/x-vcard",
  31.751 -"vcg" : "application/vnd.groove-vcard",
  31.752 -"vcs" : "text/x-vcalendar",
  31.753 -"vcx" : "application/vnd.vcx",
  31.754 -"vis" : "application/vnd.visionary",
  31.755 -"viv" : "video/vnd.vivo",
  31.756 -"vor" : "application/vnd.stardivision.writer",
  31.757 -"vox" : "application/x-authorware-bin",
  31.758 -"vrml" : "x-world/x-vrml",
  31.759 -"vsd" : "application/vnd.visio",
  31.760 -"vsf" : "application/vnd.vsf",
  31.761 -"vss" : "application/vnd.visio",
  31.762 -"vst" : "application/vnd.visio",
  31.763 -"vsw" : "application/vnd.visio",
  31.764 -"vtu" : "model/vnd.vtu",
  31.765 -"vxml" : "application/voicexml+xml",
  31.766 -"w3d" : "application/x-director",
  31.767 -"wad" : "application/x-doom",
  31.768 -"wav" : "audio/x-wav",
  31.769 -"wax" : "audio/x-ms-wax",
  31.770 -"wbmp" : "image/vnd.wap.wbmp",
  31.771 -"wbs" : "application/vnd.criticaltools.wbs+xml",
  31.772 -"wbxml" : "application/vnd.wap.wbxml",
  31.773 -"wcm" : "application/vnd.ms-works",
  31.774 -"wdb" : "application/vnd.ms-works",
  31.775 -"wiz" : "application/msword",
  31.776 -"wks" : "application/vnd.ms-works",
  31.777 -"wma" : "audio/x-ms-wma",
  31.778 -"wmd" : "application/x-ms-wmd",
  31.779 -"wmf" : "application/x-msmetafile",
  31.780 -"wmlc" : "application/vnd.wap.wmlc",
  31.781 -"wmlsc" : "application/vnd.wap.wmlscriptc",
  31.782 -"wmls" : "text/vnd.wap.wmlscript",
  31.783 -"wml" : "text/vnd.wap.wml",
  31.784 -"wm" : "video/x-ms-wm",
  31.785 -"wmv" : "video/x-ms-wmv",
  31.786 -"wmx" : "video/x-ms-wmx",
  31.787 -"wmz" : "application/x-ms-wmz",
  31.788 -"wpd" : "application/vnd.wordperfect",
  31.789 -"wpl" : "application/vnd.ms-wpl",
  31.790 -"wps" : "application/vnd.ms-works",
  31.791 -"wqd" : "application/vnd.wqd",
  31.792 -"wri" : "application/x-mswrite",
  31.793 -"wrl" : "x-world/x-vrml",
  31.794 -"wrz" : "x-world/x-vrml",
  31.795 -"wsdl" : "application/wsdl+xml",
  31.796 -"wspolicy" : "application/wspolicy+xml",
  31.797 -"wtb" : "application/vnd.webturbo",
  31.798 -"wvx" : "video/x-ms-wvx",
  31.799 -"x32" : "application/x-authorware-bin",
  31.800 -"x3d" : "application/vnd.hzn-3d-crossword",
  31.801 -"xaf" : "x-world/x-vrml",
  31.802 -"xap" : "application/x-silverlight-app",
  31.803 -"xar" : "application/vnd.xara",
  31.804 -"xbap" : "application/x-ms-xbap",
  31.805 -"xbd" : "application/vnd.fujixerox.docuworks.binder",
  31.806 -"xbm" : "image/x-xbitmap",
  31.807 -"xdm" : "application/vnd.syncml.dm+xml",
  31.808 -"xdp" : "application/vnd.adobe.xdp+xml",
  31.809 -"xdw" : "application/vnd.fujixerox.docuworks",
  31.810 -"xenc" : "application/xenc+xml",
  31.811 -"xer" : "application/patch-ops-error+xml",
  31.812 -"xfdf" : "application/vnd.adobe.xfdf",
  31.813 -"xfdl" : "application/vnd.xfdl",
  31.814 -"xht" : "application/xhtml+xml",
  31.815 -"xhtml" : "application/xhtml+xml",
  31.816 -"xhvml" : "application/xv+xml",
  31.817 -"xif" : "image/vnd.xiff",
  31.818 -"xla" : "application/vnd.ms-excel",
  31.819 -"xlam" : "application/vnd.ms-excel.addin.macroenabled.12",
  31.820 -"xlb" : "application/vnd.ms-excel",
  31.821 -"xlc" : "application/vnd.ms-excel",
  31.822 -"xlm" : "application/vnd.ms-excel",
  31.823 -"xls" : "application/vnd.ms-excel",
  31.824 -"xlsb" : "application/vnd.ms-excel.sheet.binary.macroenabled.12",
  31.825 -"xlsm" : "application/vnd.ms-excel.sheet.macroenabled.12",
  31.826 -"xlsx" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  31.827 -"xlt" : "application/vnd.ms-excel",
  31.828 -"xltm" : "application/vnd.ms-excel.template.macroenabled.12",
  31.829 -"xltx" : "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
  31.830 -"xlw" : "application/vnd.ms-excel",
  31.831 -"xml" : "application/xml",
  31.832 -"xo" : "application/vnd.olpc-sugar",
  31.833 -"xof" : "x-world/x-vrml",
  31.834 -"xop" : "application/xop+xml",
  31.835 -"xpdl" : "application/xml",
  31.836 -"xpi" : "application/x-xpinstall",
  31.837 -"xpm" : "image/x-xpixmap",
  31.838 -"xpr" : "application/vnd.is-xpr",
  31.839 -"xps" : "application/vnd.ms-xpsdocument",
  31.840 -"xpw" : "application/vnd.intercon.formnet",
  31.841 -"xpx" : "application/vnd.intercon.formnet",
  31.842 -"xsl" : "application/xml",
  31.843 -"xslt" : "application/xslt+xml",
  31.844 -"xsm" : "application/vnd.syncml+xml",
  31.845 -"xspf" : "application/xspf+xml",
  31.846 -"xul" : "application/vnd.mozilla.xul+xml",
  31.847 -"xvm" : "application/xv+xml",
  31.848 -"xvml" : "application/xv+xml",
  31.849 -"xwd" : "image/x-xwindowdump",
  31.850 -"xyz" : "chemical/x-xyz",
  31.851 -"z" : "application/x-compress",
  31.852 -"zaz" : "application/vnd.zzazz.deck+xml",
  31.853 -"zip" : "application/zip",
  31.854 -"zir" : "application/vnd.zul",
  31.855 -"zirz" : "application/vnd.zul",
  31.856 -"zmm" : "application/vnd.handheld-entertainment+xml"
  31.857 -}
  31.858 -}
    32.1 --- a/pEpForiOS/public.xcconfig	Wed May 08 12:31:03 2019 +0200
    32.2 +++ b/pEpForiOS/public.xcconfig	Fri May 17 14:16:55 2019 +0200
    32.3 @@ -6,5 +6,5 @@
    32.4  //  Copyright © 2018 p≡p Security S.A. All rights reserved.
    32.5  //
    32.6  
    32.7 -#include "secret.xcconfig"
    32.8 +#include "../pEp_for_iOS_intern/secret.xcconfig"
    32.9  
    33.1 --- a/pEpForiOSTests/AccountVerificationServiceTests.swift	Wed May 08 12:31:03 2019 +0200
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,114 +0,0 @@
    33.4 -//
    33.5 -//  AccountVerificationServiceTests.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 XCTest
   33.13 -
   33.14 -@testable import MessageModel
   33.15 -@testable import pEpForiOS
   33.16 -
   33.17 -class AccountVerificationTestDelegate: AccountVerificationServiceDelegate {
   33.18 -    let expVerified: XCTestExpectation?
   33.19 -    var verificationResult: AccountVerificationResult?
   33.20 -    var verifiedAccount: Account?
   33.21 -
   33.22 -    init(expVerified: XCTestExpectation? = nil) {
   33.23 -        self.expVerified = expVerified
   33.24 -    }
   33.25 -
   33.26 -    func verified(account: Account, service: AccountVerificationServiceProtocol,
   33.27 -                  result: AccountVerificationResult) {
   33.28 -        verifiedAccount = account
   33.29 -        verificationResult = result
   33.30 -        expVerified?.fulfill()
   33.31 -    }
   33.32 -}
   33.33 -
   33.34 -class AccountVerificationServiceTests: XCTestCase {
   33.35 -    var persistentSetup: PersistentSetup!
   33.36 -
   33.37 -    override func setUp() {
   33.38 -        persistentSetup = PersistentSetup()
   33.39 -    }
   33.40 -    
   33.41 -    override func tearDown() {
   33.42 -        persistentSetup = nil
   33.43 -    }
   33.44 -
   33.45 -    func testDirectlySuccess() {
   33.46 -        testVerification(account: SecretTestData().createVerifiableAccount(),
   33.47 -                         expectedResult: AccountVerificationResult.ok,
   33.48 -                         testDirectly: true)
   33.49 -    }
   33.50 -
   33.51 -    func testDirectlyImapFailure() {
   33.52 -        testVerification(
   33.53 -            account: SecretTestData().createImapTimeOutAccount(),
   33.54 -            expectedResult: AccountVerificationResult.imapError(
   33.55 -                .connectionTimedOut("connectionTimedOut(_:notification:)")),
   33.56 -            testDirectly: true)
   33.57 -    }
   33.58 -
   33.59 -    func testDirectlySmtpFailure() {
   33.60 -        testVerification(
   33.61 -            account: SecretTestData().createSmtpTimeOutAccount(),
   33.62 -            expectedResult: AccountVerificationResult.smtpError(
   33.63 -                .connectionTimedOut("connectionTimedOut(_:theNotification:)")),
   33.64 -            testDirectly: true)
   33.65 -    }
   33.66 -
   33.67 -    func testVerificationServiceSuccess() {
   33.68 -        testVerification(account: SecretTestData().createVerifiableAccount(),
   33.69 -                         expectedResult: AccountVerificationResult.ok,
   33.70 -                         testDirectly: false)
   33.71 -    }
   33.72 -
   33.73 -    func testVerificationServiceImapFailures() {
   33.74 -        testVerification(
   33.75 -            account: SecretTestData().createImapTimeOutAccount(),
   33.76 -            expectedResult: AccountVerificationResult.imapError(
   33.77 -                .connectionTimedOut("connectionTimedOut(_:notification:)")),
   33.78 -            testDirectly: false)
   33.79 -    }
   33.80 -
   33.81 -    func testVerificationServiceSmtpFailures() {
   33.82 -        testVerification(
   33.83 -            account: SecretTestData().createSmtpTimeOutAccount(),
   33.84 -            expectedResult: AccountVerificationResult.smtpError(
   33.85 -                .connectionTimedOut("connectionTimedOut(_:theNotification:)")),
   33.86 -            testDirectly: false)
   33.87 -    }
   33.88 -
   33.89 -    // MARK: HELPER
   33.90 -
   33.91 -    func testVerification(account: Account, expectedResult: AccountVerificationResult,
   33.92 -                          testDirectly: Bool) {
   33.93 -        account.save()
   33.94 -
   33.95 -        let expVerified = expectation(description: "account verified")
   33.96 -        let delegate = AccountVerificationTestDelegate(expVerified: expVerified)
   33.97 -
   33.98 -        let asService = AccountVerificationService()
   33.99 -        let verificationService = VerificationService(parentName: #function)
  33.100 -
  33.101 -        if testDirectly {
  33.102 -            asService.delegate = delegate
  33.103 -            asService.verify(account: account)
  33.104 -        } else {
  33.105 -            verificationService.requestVerification(account: account, delegate: delegate)
  33.106 -        }
  33.107 -
  33.108 -        waitForExpectations(timeout: TestUtil.waitTime, handler: { error in
  33.109 -            XCTAssertNil(error)
  33.110 -            guard let result = delegate.verificationResult else {
  33.111 -                XCTFail()
  33.112 -                return
  33.113 -            }
  33.114 -            XCTAssertEqual(result, expectedResult)
  33.115 -        })
  33.116 -    }
  33.117 -}
    34.1 --- a/pEpForiOSTests/HandshakeTests.swift	Wed May 08 12:31:03 2019 +0200
    34.2 +++ b/pEpForiOSTests/HandshakeTests.swift	Fri May 17 14:16:55 2019 +0200
    34.3 @@ -60,7 +60,7 @@
    34.4  
    34.5          let theAttachments = pEpMessage.attachments ?? []
    34.6          XCTAssertEqual(theAttachments.count, 1)
    34.7 -        XCTAssertEqual(theAttachments[0].mimeType, MimeTypeUtil.contentTypeApplicationPGPKeys)
    34.8 +        XCTAssertEqual(theAttachments[0].mimeType, ContentTypeUtils.ContentType.pgpKeys)
    34.9  
   34.10          guard let optFields = pEpMessage.optionalFields else {
   34.11              XCTFail("expected optional_fields to be defined")
    35.1 --- a/pEpForiOSTests/MailParsingTests.swift	Wed May 08 12:31:03 2019 +0200
    35.2 +++ b/pEpForiOSTests/MailParsingTests.swift	Fri May 17 14:16:55 2019 +0200
    35.3 @@ -60,7 +60,7 @@
    35.4  
    35.5          let theAttachments = pEpMessage.attachments ?? []
    35.6          XCTAssertEqual(theAttachments.count, 1)
    35.7 -        XCTAssertEqual(theAttachments[0].mimeType, MimeTypeUtil.contentTypeApplicationPGPKeys)
    35.8 +        XCTAssertEqual(theAttachments[0].mimeType, ContentTypeUtils.ContentType.pgpKeys)
    35.9  
   35.10          guard let optFields = pEpMessage.optionalFields else {
   35.11              XCTFail("expected optional_fields to be defined")
    36.1 --- a/pEpForiOSTests/MiscTests.swift	Wed May 08 12:31:03 2019 +0200
    36.2 +++ b/pEpForiOSTests/MiscTests.swift	Fri May 17 14:16:55 2019 +0200
    36.3 @@ -33,9 +33,9 @@
    36.4      }
    36.5  
    36.6      func testMimeTypeJson() {
    36.7 -        let mimeTypeController = MimeTypeUtil()
    36.8 -        let s = mimeTypeController?.mimeType(fileExtension: "pdf")
    36.9 -        XCTAssertEqual(s, "application/pdf")
   36.10 +        let mimeTypeController = MimeTypeUtils()
   36.11 +        let s = mimeTypeController?.mimeType(fromFileExtension: "pdf")
   36.12 +        XCTAssertEqual(s, MimeTypeUtils.MimesType.pdf)
   36.13      }
   36.14  
   36.15      func testBinaryIndex() {
    37.1 --- a/pEpForiOSTests/Models/Folder/FolderViewModelTest.swift	Wed May 08 12:31:03 2019 +0200
    37.2 +++ b/pEpForiOSTests/Models/Folder/FolderViewModelTest.swift	Fri May 17 14:16:55 2019 +0200
    37.3 @@ -99,11 +99,4 @@
    37.4          CdAccount.deleteAll()
    37.5          viewmodel = FolderViewModel(withFoldersIn: nil, includeUnifiedInbox: withUnifiedInbox)
    37.6      }
    37.7 -    
    37.8 -    class VerificationServiceMock: VerificationServiceProtocol {
    37.9 -        func requestVerification(account: Account, delegate: AccountVerificationServiceDelegate) {
   37.10 -            
   37.11 -        }
   37.12 -    }
   37.13 -
   37.14  }
    38.1 --- a/pEpForiOSTests/Models/LoginViewModelTests.swift	Wed May 08 12:31:03 2019 +0200
    38.2 +++ b/pEpForiOSTests/Models/LoginViewModelTests.swift	Fri May 17 14:16:55 2019 +0200
    38.3 @@ -25,7 +25,7 @@
    38.4  }
    38.5  
    38.6  class LoginViewModelTests: CoreDataDrivenTestBase {
    38.7 -    class TestVerificationService: VerifiableAccountProtocol {
    38.8 +    class TestVerifiableAccount: VerifiableAccountProtocol {
    38.9          let accountSettings: TestDataBase.AccountSettings
   38.10          let expLookedUp: XCTestExpectation
   38.11  
   38.12 @@ -49,6 +49,10 @@
   38.13          var trustedImapServer: Bool = false
   38.14          var verifiableAccountDelegate: VerifiableAccountDelegate?
   38.15  
   38.16 +        let isValidName = false
   38.17 +
   38.18 +        let isValidUser = false
   38.19 +
   38.20          func verify() throws {
   38.21              XCTAssertEqual(address, accountSettings.idAddress)
   38.22  
   38.23 @@ -105,9 +109,9 @@
   38.24  //        }
   38.25  
   38.26          let expLookedUp = expectation(description: "expLookedUp")
   38.27 -        let verificationService =
   38.28 -            TestVerificationService(accountSettings: accountSettings, expLookedUp: expLookedUp)
   38.29 -        let vm = LoginViewModel(verificationService: verificationService)
   38.30 +        let verifiableAccount =
   38.31 +            TestVerifiableAccount(accountSettings: accountSettings, expLookedUp: expLookedUp)
   38.32 +        let vm = LoginViewModel(verifiableAccount: verifiableAccount)
   38.33          let errorHandler = ErrorHandler()
   38.34          vm.loginViewModelLoginErrorDelegate = errorHandler
   38.35          vm.login(accountName: accountSettings.idAddress,
    39.1 --- a/pEpForiOSTests/Models/Settings/AccountSettingsViewModelTest.swift	Wed May 08 12:31:03 2019 +0200
    39.2 +++ b/pEpForiOSTests/Models/Settings/AccountSettingsViewModelTest.swift	Fri May 17 14:16:55 2019 +0200
    39.3 @@ -63,15 +63,17 @@
    39.4      }
    39.5  
    39.6      func testUpdate() {
    39.7 -        let address = "fakeAddress"
    39.8 +        let address = "localhost"
    39.9          let login = "fakelogin"
   39.10          let name = "fakeName"
   39.11          let password = "fakePassword"
   39.12 +        let portString = "1"
   39.13 +        let portInt = UInt16(portString)!
   39.14  
   39.15          setUpViewModel()
   39.16  
   39.17          let server = AccountSettingsViewModel.ServerViewModel(address: address,
   39.18 -                                                              port: "123",
   39.19 +                                                              port: portString,
   39.20                                                                transport: "StartTls")
   39.21  
   39.22          let verifyExpectation =
   39.23 @@ -89,24 +91,18 @@
   39.24  
   39.25          waitForExpectations(timeout: UnitTestUtils.asyncWaitTime)
   39.26  
   39.27 -        // TODO: What to test here?
   39.28 -        /*
   39.29 -        let smtp = viewModel.account.smtpServer
   39.30 -        let imap = viewModel.account.imapServer
   39.31 +        guard let verifier = viewModel.verifiableAccount else {
   39.32 +            XCTFail()
   39.33 +            return
   39.34 +        }
   39.35  
   39.36 -        XCTAssertEqual(smtp?.credentials.loginName, login)
   39.37 -        XCTAssertEqual(smtp?.credentials.password, password)
   39.38 -        XCTAssertEqual(imap?.credentials.loginName, login)
   39.39 -        XCTAssertEqual(imap?.credentials.password, password)
   39.40 -
   39.41 -        XCTAssertEqual(imap?.address, address)
   39.42 -        XCTAssertEqual(imap?.port, 123)
   39.43 -        XCTAssertEqual(imap?.transport, .startTls)
   39.44 -
   39.45 -        XCTAssertEqual(smtp?.address, address)
   39.46 -        XCTAssertEqual(smtp?.port, 123)
   39.47 -        XCTAssertEqual(smtp?.transport, .startTls)
   39.48 -         */
   39.49 +        XCTAssertEqual(verifier.loginName, login)
   39.50 +        XCTAssertEqual(verifier.password, password)
   39.51 +        XCTAssertEqual(verifier.serverIMAP, address)
   39.52 +        XCTAssertEqual(verifier.serverSMTP, address)
   39.53 +        XCTAssertEqual(verifier.portIMAP, portInt)
   39.54 +        XCTAssertEqual(verifier.portSMTP, portInt)
   39.55 +        XCTAssertNil(verifier.accessToken)
   39.56      }
   39.57  
   39.58      public func testSectionIsValid() {
   39.59 @@ -133,9 +129,7 @@
   39.60          delegate.expectationDidVerifyCalled = verifyExpectation
   39.61          viewModel.delegate = delegate
   39.62  
   39.63 -        viewModel.verified(account: account,
   39.64 -                           service: AccountVerificationService(),
   39.65 -                           result: .ok)
   39.66 +        viewModel.didEndVerification(result: .success(()))
   39.67  
   39.68          waitForExpectations(timeout: UnitTestUtils.waitTime)
   39.69      }
   39.70 @@ -152,7 +146,7 @@
   39.71      var expectationDidVerifyCalled: XCTestExpectation?
   39.72      var error: Error? = nil
   39.73  
   39.74 -    func didVerify(result: AccountVerificationResult, accountInput: VerifiableAccountProtocol?) {
   39.75 +    func didVerify(result: AccountVerificationResult) {
   39.76          switch result {
   39.77          case .ok:
   39.78              self.error = nil
    40.1 --- a/pEpForiOSTests/PepAdapterTests.swift	Wed May 08 12:31:03 2019 +0200
    40.2 +++ b/pEpForiOSTests/PepAdapterTests.swift	Fri May 17 14:16:55 2019 +0200
    40.3 @@ -13,7 +13,6 @@
    40.4  import PEPObjCAdapterFramework
    40.5  
    40.6  class PepAdapterTests: XCTestCase {
    40.7 -    let comp = "PepAdapterTests"
    40.8      let identityMe = PEPIdentity(address: "some@mail.com",
    40.9                                   userID: CdIdentity.pEpOwnUserID,
   40.10                                   userName: "This is me",
    41.1 --- a/pEpForiOSTests/Service/VerifiableAccountTest.swift	Wed May 08 12:31:03 2019 +0200
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,162 +0,0 @@
    41.4 -//
    41.5 -//  VerifiableAccountTest.swift
    41.6 -//  pEpForiOSTests
    41.7 -//
    41.8 -//  Created by Dirk Zimmermann on 16.04.19.
    41.9 -//  Copyright © 2019 p≡p Security S.A. All rights reserved.
   41.10 -//
   41.11 -
   41.12 -import XCTest
   41.13 -
   41.14 -import MessageModel
   41.15 -@testable import pEpForiOS
   41.16 -
   41.17 -class VerifiableAccountTest: XCTestCase {
   41.18 -    func testBasicSuccess() {
   41.19 -        let verifier = VerifiableAccount()
   41.20 -        var verifierType: VerifiableAccountProtocol = verifier
   41.21 -        SecretTestData().populateWorkingAccount(
   41.22 -            verifiableAccount: &verifierType)
   41.23 -        let expDidVerify = expectation(description: "expDidVerify")
   41.24 -        let delegate = VerifiableAccountTestDelegate(expDidVerify: expDidVerify)
   41.25 -        try! check(verifier: &verifierType, delegate: delegate)
   41.26 -        wait(for: [expDidVerify], timeout: TestUtil.waitTime)
   41.27 -
   41.28 -        guard let theResult = delegate.result else {
   41.29 -            XCTFail()
   41.30 -            return
   41.31 -        }
   41.32 -        switch theResult {
   41.33 -        case .success(()):
   41.34 -            break
   41.35 -        case .failure(_):
   41.36 -            XCTFail()
   41.37 -        }
   41.38 -    }
   41.39 -
   41.40 -    func testFailingValidation() {
   41.41 -        let (exceptionOnVerify, exceptionOnSave) = checkFailingValidation() {
   41.42 -            var newOne = $0
   41.43 -            newOne.address = nil
   41.44 -            return newOne
   41.45 -        }
   41.46 -        XCTAssertTrue(exceptionOnVerify)
   41.47 -        XCTAssertTrue(exceptionOnSave)
   41.48 -    }
   41.49 -
   41.50 -    func testBasicFailingVerification() {
   41.51 -        let result = checkBasicVerification() { v in
   41.52 -            var verifiable = v
   41.53 -
   41.54 -            // This should make it fail quickly
   41.55 -            verifiable.serverIMAP = "localhost"
   41.56 -            verifiable.portIMAP = 5
   41.57 -            verifiable.serverSMTP = "localhost"
   41.58 -            verifiable.portSMTP = 5
   41.59 -
   41.60 -            return verifiable
   41.61 -        }
   41.62 -        switch result {
   41.63 -        case .success(_):
   41.64 -            XCTFail()
   41.65 -        case .failure(_):
   41.66 -            break
   41.67 -        }
   41.68 -    }
   41.69 -
   41.70 -    func testBasicFailingVerificationWithWrongPassword() {
   41.71 -        let result = checkBasicVerification() { v in
   41.72 -            var verifiable = v
   41.73 -
   41.74 -            verifiable.password = "xxxxxxxxxx"
   41.75 -
   41.76 -            return verifiable
   41.77 -        }
   41.78 -        switch result {
   41.79 -        case .success(_):
   41.80 -            XCTFail()
   41.81 -        case .failure(_):
   41.82 -            break
   41.83 -        }
   41.84 -    }
   41.85 -
   41.86 -    // MARK: Helpers
   41.87 -
   41.88 -    /// Tries `verify()` and `save()` on the given `VerifiableAccountProtocol`.
   41.89 -    /// - Returns: A tuple of Bool denoting if `verify()` and `save()` threw exceptions.
   41.90 -    func checkFailingValidation(
   41.91 -        modifier: (VerifiableAccountProtocol) -> VerifiableAccountProtocol) -> (Bool, Bool) {
   41.92 -        let verifier = VerifiableAccount()
   41.93 -        var verifierType: VerifiableAccountProtocol = verifier
   41.94 -        SecretTestData().populateWorkingAccount(
   41.95 -            verifiableAccount: &verifierType)
   41.96 -
   41.97 -        // Invalidate it
   41.98 -        var verifierToBeUsed = modifier(verifierType)
   41.99 -
  41.100 -        var exceptionHit1 = false
  41.101 -        do {
  41.102 -            try check(verifier: &verifierToBeUsed, delegate: nil)
  41.103 -        } catch {
  41.104 -            exceptionHit1 = true
  41.105 -        }
  41.106 -
  41.107 -        var exceptionHit2 = false
  41.108 -        do {
  41.109 -            try check(verifier: &verifierToBeUsed, delegate: nil)
  41.110 -        } catch {
  41.111 -            exceptionHit2 = true
  41.112 -        }
  41.113 -
  41.114 -        return (exceptionHit1, exceptionHit2)
  41.115 -    }
  41.116 -
  41.117 -    func check(verifier: inout VerifiableAccountProtocol,
  41.118 -               delegate: VerifiableAccountDelegate?) throws {
  41.119 -        verifier.verifiableAccountDelegate = delegate
  41.120 -        try verifier.verify()
  41.121 -    }
  41.122 -
  41.123 -    enum TestError: Error {
  41.124 -        case noResult
  41.125 -    }
  41.126 -
  41.127 -    /// Expects a failure, lets caller modify the `VerifiableAccountProtocol`.
  41.128 -    func checkBasicVerification(
  41.129 -        modifier: (VerifiableAccountProtocol) -> VerifiableAccountProtocol)
  41.130 -        -> Result<Void, Error> {
  41.131 -            let verifier = VerifiableAccount()
  41.132 -            var verifiable: VerifiableAccountProtocol = verifier
  41.133 -            SecretTestData().populateWorkingAccount(
  41.134 -                verifiableAccount: &verifiable)
  41.135 -
  41.136 -            verifiable = modifier(verifiable)
  41.137 -
  41.138 -            let expDidVerify = expectation(description: "expDidVerify")
  41.139 -            let delegate = VerifiableAccountTestDelegate(expDidVerify: expDidVerify)
  41.140 -            try! check(verifier: &verifiable, delegate: delegate)
  41.141 -            wait(for: [expDidVerify], timeout: TestUtil.waitTime)
  41.142 -
  41.143 -            guard let result = delegate.result else {
  41.144 -                XCTFail()
  41.145 -                return .failure(TestError.noResult)
  41.146 -            }
  41.147 -
  41.148 -            return result
  41.149 -    }
  41.150 -}
  41.151 -
  41.152 -class VerifiableAccountTestDelegate: VerifiableAccountDelegate {
  41.153 -    var result: Result<Void, Error>?
  41.154 -
  41.155 -    let expDidVerify: XCTestExpectation
  41.156 -
  41.157 -    init(expDidVerify: XCTestExpectation) {
  41.158 -        self.expDidVerify = expDidVerify
  41.159 -    }
  41.160 -
  41.161 -    func didEndVerification(result: Result<Void, Error>) {
  41.162 -        self.result = result
  41.163 -        expDidVerify.fulfill()
  41.164 -    }
  41.165 -}
    42.1 --- a/pEpForiOSTests/StringHTMLExtensionTests.swift	Wed May 08 12:31:03 2019 +0200
    42.2 +++ b/pEpForiOSTests/StringHTMLExtensionTests.swift	Fri May 17 14:16:55 2019 +0200
    42.3 @@ -114,7 +114,7 @@
    42.4          let alt1 = "Attached Image 1 (jpg)"
    42.5  
    42.6          let theData = "Not an image".data(using: .utf8)
    42.7 -        let theMimeType = MimeTypeUtil.jpegMimeType
    42.8 +        let theMimeType = MimeTypeUtils.MimesType.jpeg
    42.9          let attachment = Attachment.create(
   42.10              data: theData, mimeType: theMimeType, fileName: "cid:\(cid1)",
   42.11              size: theData?.count)
    43.1 --- a/pEpForiOSTests/TestUtils/PEPMessage+TestExtension.swift	Wed May 08 12:31:03 2019 +0200
    43.2 +++ b/pEpForiOSTests/TestUtils/PEPMessage+TestExtension.swift	Fri May 17 14:16:55 2019 +0200
    43.3 @@ -14,10 +14,12 @@
    43.4  
    43.5  extension PEPMessage {
    43.6      public func isLikelyPEPEncrypted() -> Bool {
    43.7 -        let theAttachments = attachments ?? []
    43.8 -        return theAttachments.count == 2 &&
    43.9 -            theAttachments[0].mimeType == "application/pgp-encrypted" &&
   43.10 -            theAttachments[1].mimeType == "application/octet-stream" &&
   43.11 -            theAttachments[1].filename == "file://msg.asc"
   43.12 +        guard let attachments = attachments else {
   43.13 +            return false
   43.14 +        }
   43.15 +        return attachments.count == 2 &&
   43.16 +            attachments[0].mimeType == MimeTypeUtils.MimesType.pgpEncrypted &&
   43.17 +            attachments[1].mimeType == MimeTypeUtils.MimesType.defaultMimeType &&
   43.18 +            attachments[1].filename == "file://msg.asc"
   43.19      }
   43.20  }
    44.1 --- a/pEpForiOSTests/TestUtils/TestDataBase.swift	Wed May 08 12:31:03 2019 +0200
    44.2 +++ b/pEpForiOSTests/TestUtils/TestDataBase.swift	Fri May 17 14:16:55 2019 +0200
    44.3 @@ -13,6 +13,15 @@
    44.4  import PEPObjCAdapterFramework
    44.5  import PantomimeFramework
    44.6  
    44.7 +/// Base class for test data.
    44.8 +/// - Note:
    44.9 +///   1. This class is used both in MessageModel and the app,
   44.10 +///      so it's _duplicated code_ for the testing targets.
   44.11 +///   2. Make sure that, in your SecretTestData, you override:
   44.12 +///      * `populateAccounts` if you don't use the greenmail local server for testing,
   44.13 +///        or you want to test against other servers for various reasons.
   44.14 +///      * `populateVerifiableAccounts` in order to provide verifiable servers, to test
   44.15 +///        the verification parts.
   44.16  class TestDataBase {
   44.17      struct AccountSettings {
   44.18          var accountName: String?
   44.19 @@ -170,6 +179,7 @@
   44.20          /// Transfers the account data into a `VerifiableAccountProtocol`
   44.21          /// that you then can verify the acconut data with.
   44.22          func populate(verifiableAccount: inout VerifiableAccountProtocol) {
   44.23 +            verifiableAccount.userName = accountName
   44.24              verifiableAccount.address = idAddress
   44.25              verifiableAccount.loginName = imapLoginName
   44.26              verifiableAccount.accessToken = nil
   44.27 @@ -214,6 +224,32 @@
   44.28          addLocalTestAccount(userName: "test003")
   44.29      }
   44.30  
   44.31 +    /**
   44.32 +     Accounts needed for testing LAS, that is they need to be registered
   44.33 +     in the LAS DB or provide (correct) DNS SRV for IMAP and SMTP.
   44.34 +     - Note: Override this in your SecretTestData to something that's working.
   44.35 +     */
   44.36 +    func populateVerifiableAccounts() {
   44.37 +        append(verifiableAccountSettings: AccountSettings(
   44.38 +            accountName: "Whatever_you_want",
   44.39 +            idAddress: "whatever_you_want@yahoo.com",
   44.40 +            idUserName: "whatever_you_want@yahoo.com",
   44.41 +
   44.42 +            imapServerAddress: "imap.mail.yahoo.com",
   44.43 +            imapServerType: Server.ServerType.imap,
   44.44 +            imapServerTransport: Server.Transport.tls,
   44.45 +            imapServerPort: 993,
   44.46 +
   44.47 +            smtpServerAddress: "smtp.mail.yahoo.com",
   44.48 +            smtpServerType: Server.ServerType.smtp,
   44.49 +            smtpServerTransport: Server.Transport.tls,
   44.50 +            smtpServerPort: 465,
   44.51 +
   44.52 +            password: "whatever_you_want"))
   44.53 +
   44.54 +        fatalError("Abstract method. Must be overridden")
   44.55 +    }
   44.56 +
   44.57      private func addLocalTestAccount(userName: String) {
   44.58          let address = "\(userName)@localhost"
   44.59          append(accountSettings: AccountSettings(
   44.60 @@ -237,31 +273,6 @@
   44.61      }
   44.62  
   44.63      /**
   44.64 -     Accounts needed for testing LAS, that is they need to be registered
   44.65 -     in the LAS DB or provide (correct) DNS SRV for IMAP and SMTP.
   44.66 -     */
   44.67 -    func populateVerifiableAccounts() {
   44.68 -        append(verifiableAccountSettings: AccountSettings(
   44.69 -            accountName: "Whatever_you_want",
   44.70 -            idAddress: "whatever_you_want@yahoo.com",
   44.71 -            idUserName: "whatever_you_want@yahoo.com",
   44.72 -
   44.73 -            imapServerAddress: "imap.mail.yahoo.com",
   44.74 -            imapServerType: Server.ServerType.imap,
   44.75 -            imapServerTransport: Server.Transport.tls,
   44.76 -            imapServerPort: 993,
   44.77 -
   44.78 -            smtpServerAddress: "smtp.mail.yahoo.com",
   44.79 -            smtpServerType: Server.ServerType.smtp,
   44.80 -            smtpServerTransport: Server.Transport.tls,
   44.81 -            smtpServerPort: 465,
   44.82 -
   44.83 -            password: "whatever_you_want"))
   44.84 -
   44.85 -        fatalError("Abstract method. Must be overridden")
   44.86 -    }
   44.87 -
   44.88 -    /**
   44.89       - Returns: A valid `CdAccount`.
   44.90       */
   44.91      func createWorkingCdAccount(number: Int = 0) -> CdAccount {
   44.92 @@ -390,8 +401,8 @@
   44.93          return createImapTimeOutAccountSettings().account()
   44.94      }
   44.95  
   44.96 -    func populateWorkingAccount(number: Int = 0,
   44.97 -                                verifiableAccount: inout VerifiableAccountProtocol) {
   44.98 +    func populateVerifiableAccount(number: Int = 0,
   44.99 +                                   verifiableAccount: inout VerifiableAccountProtocol) {
  44.100          createVerifiableAccountSettings(number: number).populate(
  44.101              verifiableAccount: &verifiableAccount)
  44.102      }
    45.1 --- a/pEpForiOSTests/TestUtils/TestUtil.swift	Wed May 08 12:31:03 2019 +0200
    45.2 +++ b/pEpForiOSTests/TestUtils/TestUtil.swift	Fri May 17 14:16:55 2019 +0200
    45.3 @@ -507,7 +507,7 @@
    45.4          let contentDisposition = inlined ? Attachment.ContentDispositionType.inline : .attachment
    45.5  
    45.6          return Attachment.create(data: imageData,
    45.7 -                          mimeType: MimeTypeUtil.jpegMimeType,
    45.8 +                          mimeType: MimeTypeUtils.MimesType.jpeg,
    45.9                            fileName: imageFileName,
   45.10                            contentDisposition: contentDisposition)
   45.11      }
    46.1 --- a/pEpForiOSTests/URL+MIME.swift	Wed May 08 12:31:03 2019 +0200
    46.2 +++ b/pEpForiOSTests/URL+MIME.swift	Fri May 17 14:16:55 2019 +0200
    46.3 @@ -12,15 +12,15 @@
    46.4  import pEpIOSToolbox
    46.5  import MessageModel
    46.6  
    46.7 -class URL_MIME: XCTestCase {
    46.8 +class URL_MimeTest: XCTestCase {
    46.9      let pathBuilder = "file://ma/path/to/nice_pic"
   46.10 -    let mimeUtil = MimeTypeUtil()
   46.11 +    let mimeUtils = MimeTypeUtils()
   46.12  
   46.13      func testJpg() {
   46.14          let jpgExt = "jpg"
   46.15          let url = urlWithExtension(ext: jpgExt)
   46.16 -        let testee = url.mimeType()
   46.17 -        let expected = mimeUtil?.mimeType(fileExtension: jpgExt)
   46.18 +        let testee = mimeUtils?.mimeType(fromURL: url)
   46.19 +        let expected = mimeUtils?.mimeType(fromFileExtension: jpgExt)
   46.20          XCTAssertEqual(testee, expected)
   46.21      }
   46.22  
    47.1 --- a/pEpForiOSUITests/NewAccountSetupUITest.swift	Wed May 08 12:31:03 2019 +0200
    47.2 +++ b/pEpForiOSUITests/NewAccountSetupUITest.swift	Fri May 17 14:16:55 2019 +0200
    47.3 @@ -25,7 +25,7 @@
    47.4  
    47.5          dismissInitialSystemAlerts()
    47.6  
    47.7 -        let account = SecretUITestData.workingAccount1
    47.8 +        let account = secretTestData().workingAccount1
    47.9          newAccountSetup(account: account)
   47.10          waitForever()
   47.11      }
   47.12 @@ -35,7 +35,7 @@
   47.13  
   47.14          dismissInitialSystemAlerts()
   47.15  
   47.16 -        let account = SecretUITestData.workingAccount2
   47.17 +        let account = secretTestData().workingAccount2
   47.18          newAccountSetup(account: account)
   47.19          waitForever()
   47.20      }
   47.21 @@ -43,14 +43,14 @@
   47.22      func testAdditionalAccount() {
   47.23          app().launch()
   47.24          addAccount()
   47.25 -        let account = SecretUITestData.workingAccount3
   47.26 +        let account = secretTestData().workingAccount3
   47.27          newAccountSetup(account: account)
   47.28          waitForever()
   47.29      }
   47.30  
   47.31      func testAdditionalManualAccount() {
   47.32          app().launch()
   47.33 -        addAdditionalManual(account: SecretUITestData.manualAccount)
   47.34 +        addAdditionalManual(account: secretTestData().manualAccount)
   47.35      }
   47.36  
   47.37      func testAutoAccountPlusManual() {
   47.38 @@ -58,10 +58,10 @@
   47.39  
   47.40          dismissInitialSystemAlerts()
   47.41  
   47.42 -        let account1 = SecretUITestData.workingAccount1
   47.43 +        let account1 = secretTestData().workingAccount1
   47.44          newAccountSetup(account: account1)
   47.45  
   47.46 -        addAdditionalManual(account: SecretUITestData.manualAccount)
   47.47 +        addAdditionalManual(account: secretTestData().manualAccount)
   47.48      }
   47.49  
   47.50      func testTwoInitialAccounts() {
   47.51 @@ -69,12 +69,12 @@
   47.52  
   47.53          dismissInitialSystemAlerts()
   47.54  
   47.55 -        let account1 = SecretUITestData.workingAccount1
   47.56 +        let account1 = secretTestData().workingAccount1
   47.57          newAccountSetup(account: account1)
   47.58  
   47.59          addAccount()
   47.60  
   47.61 -        let account2 = SecretUITestData.workingAccount2
   47.62 +        let account2 = secretTestData().workingAccount2
   47.63          newAccountSetup(account: account2)
   47.64          waitForever()
   47.65      }
   47.66 @@ -86,7 +86,36 @@
   47.67  
   47.68          dismissInitialSystemAlerts()
   47.69  
   47.70 -        let account = SecretUITestData.manualAccount
   47.71 +        var account = secretTestData().workingAccount1
   47.72 +
   47.73 +        // Wrong password should prevent the automatic login
   47.74 +        let correctPassword = account.password
   47.75 +        account.password += "ShouldNotWork"
   47.76 +
   47.77 +        newAccountSetup(account: account)
   47.78 +
   47.79 +        switchToManualConfig()
   47.80 +
   47.81 +        // Use correct password for the manual setup
   47.82 +        account.password = correctPassword
   47.83 +
   47.84 +        manualNewAccountSetup(account)
   47.85 +
   47.86 +        waitForever()
   47.87 +    }
   47.88 +
   47.89 +    func testNewAccountSetupManualThatFails() {
   47.90 +        let theApp = app()
   47.91 +
   47.92 +        theApp.launch()
   47.93 +
   47.94 +        dismissInitialSystemAlerts()
   47.95 +
   47.96 +        var account = secretTestData().workingAccount1
   47.97 +
   47.98 +        // Make sure this account will fails, both in auto and manual modes
   47.99 +        account.password += "ShouldNotWork"
  47.100 +
  47.101          newAccountSetup(account: account)
  47.102  
  47.103          switchToManualConfig()
  47.104 @@ -101,7 +130,7 @@
  47.105  
  47.106          dismissInitialSystemAlerts()
  47.107  
  47.108 -        let account = SecretUITestData.gmailOAuth2Account
  47.109 +        let account = secretTestData().gmailOAuth2Account
  47.110          newAccountSetup(account: account, enterPassword: false)
  47.111          waitForever()
  47.112      }
  47.113 @@ -111,7 +140,7 @@
  47.114  
  47.115          dismissInitialSystemAlerts()
  47.116  
  47.117 -        let account = SecretUITestData.yahooOAuth2Account
  47.118 +        let account = secretTestData().yahooOAuth2Account
  47.119          newAccountSetup(account: account, enterPassword: false)
  47.120          waitForever()
  47.121      }
  47.122 @@ -124,6 +153,10 @@
  47.123          return app
  47.124      }
  47.125  
  47.126 +    func secretTestData() -> UITestDataProtocol {
  47.127 +        return SecretUITestData()
  47.128 +    }
  47.129 +
  47.130      /*
  47.131       Use if you want to wait forever. May be useful for debugging.
  47.132       */
  47.133 @@ -151,7 +184,7 @@
  47.134  
  47.135          tf = tablesQuery.cells.secureTextFields["password"]
  47.136          tf.tap()
  47.137 -        typeTextIfEmpty(textField: tf, text: account.password)
  47.138 +        tf.typeText(account.password)
  47.139  
  47.140          theApp.navigationBars.buttons["Next"].tap()
  47.141  
    48.1 --- a/pEpForiOSUITests/UITestDataProtocol.swift	Wed May 08 12:31:03 2019 +0200
    48.2 +++ b/pEpForiOSUITests/UITestDataProtocol.swift	Fri May 17 14:16:55 2019 +0200
    48.3 @@ -9,10 +9,11 @@
    48.4  import Foundation
    48.5  
    48.6  protocol UITestDataProtocol {
    48.7 -    static var workingAccount1: UIAccount { get }
    48.8 -    static var workingAccount2: UIAccount  { get }
    48.9 -    static var workingYahooAccount: UIAccount { get }
   48.10 -    static var gmailOAuth2Account: UIAccount { get }
   48.11 -    static var yahooOAuth2Account: UIAccount { get }
   48.12 -    static var manualAccount: UIAccount { get }
   48.13 +    var workingAccount1: UIAccount { get }
   48.14 +    var workingAccount2: UIAccount  { get }
   48.15 +    var workingAccount3: UIAccount  { get }
   48.16 +    var workingYahooAccount: UIAccount { get }
   48.17 +    var gmailOAuth2Account: UIAccount { get }
   48.18 +    var yahooOAuth2Account: UIAccount { get }
   48.19 +    var manualAccount: UIAccount { get }
   48.20  }
    49.1 --- a/subModules/pEpIOSToolbox/pEpIOSToolbox.xcodeproj/project.pbxproj	Wed May 08 12:31:03 2019 +0200
    49.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolbox.xcodeproj/project.pbxproj	Fri May 17 14:16:55 2019 +0200
    49.3 @@ -16,7 +16,6 @@
    49.4  		37904569223FA52B006DAB3B /* NetworkReachibilityMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37904567223FA52B006DAB3B /* NetworkReachibilityMock.swift */; };
    49.5  		3790456A223FA52B006DAB3B /* ReachabilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37904568223FA52B006DAB3B /* ReachabilityTests.swift */; };
    49.6  		37954C6E227C90C10099B8D8 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37954C6D227C90C10099B8D8 /* Log.swift */; };
    49.7 -		435F5129221FF9D7006EB11F /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435F5128221FF9D7006EB11F /* Constants.swift */; };
    49.8  		B70A3A5522005BD400EDCE61 /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70A3A5422005BD400EDCE61 /* Date+Extension.swift */; };
    49.9  		B70A3A5722005BE300EDCE61 /* NSRegularExpression+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70A3A5622005BE300EDCE61 /* NSRegularExpression+Extension.swift */; };
   49.10  		B70A3A7322006B9F00EDCE61 /* SystemUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = B70A3A7222006B9E00EDCE61 /* SystemUtils.swift */; };
   49.11 @@ -66,7 +65,6 @@
   49.12  		37904567223FA52B006DAB3B /* NetworkReachibilityMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkReachibilityMock.swift; sourceTree = "<group>"; };
   49.13  		37904568223FA52B006DAB3B /* ReachabilityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReachabilityTests.swift; sourceTree = "<group>"; };
   49.14  		37954C6D227C90C10099B8D8 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
   49.15 -		435F5128221FF9D7006EB11F /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = ../../../../Submodules/pEpIOSToolbox/pEpIOSToolbox/Other/Constants.swift; sourceTree = "<group>"; };
   49.16  		B70A3A5422005BD400EDCE61 /* Date+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Extension.swift"; sourceTree = "<group>"; };
   49.17  		B70A3A5622005BE300EDCE61 /* NSRegularExpression+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSRegularExpression+Extension.swift"; sourceTree = "<group>"; };
   49.18  		B70A3A7222006B9E00EDCE61 /* SystemUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemUtils.swift; sourceTree = "<group>"; };
   49.19 @@ -263,7 +261,6 @@
   49.20  				B7A46C4F220C1F0C0027CCB5 /* MiscUtil.swift */,
   49.21  				B7DB7F512213120B003968DA /* SortedSet.swift */,
   49.22  				B70A3A7222006B9E00EDCE61 /* SystemUtils.swift */,
   49.23 -				435F5128221FF9D7006EB11F /* Constants.swift */,
   49.24  			);
   49.25  			path = Other;
   49.26  			sourceTree = "<group>";
   49.27 @@ -388,7 +385,6 @@
   49.28  				B7465DE72211E969008A1708 /* CGRect+Util.swift in Sources */,
   49.29  				B7465DCC2211BEEA008A1708 /* Tuple.swift in Sources */,
   49.30  				37904562223FA486006DAB3B /* NetworkReachabilityProtocol.swift in Sources */,
   49.31 -				435F5129221FF9D7006EB11F /* Constants.swift in Sources */,
   49.32  				B7A46C50220C1F0C0027CCB5 /* MiscUtil.swift in Sources */,
   49.33  				B70A3A7322006B9F00EDCE61 /* SystemUtils.swift in Sources */,
   49.34  				B7936E3D220DD8F5003B39E6 /* NSAttributedString+Extensions.swift in Sources */,
    50.1 --- a/subModules/pEpIOSToolbox/pEpIOSToolbox/Foundation/NSAttributedString+Parsing.swift	Wed May 08 12:31:03 2019 +0200
    50.2 +++ b/subModules/pEpIOSToolbox/pEpIOSToolbox/Foundation/NSAttributedString+Parsing.swift	Fri May 17 14:16:55 2019 +0200
    50.3 @@ -11,7 +11,6 @@
    50.4  
    50.5  public protocol NSAttributedStringParsingDelegate: class {
    50.6      func stringFor(attachment: NSTextAttachment) -> String?
    50.7 -    func stringFor(string: String) -> String?
    50.8  }
    50.9  
   50.10  public extension NSAttributedString {
   50.11 @@ -28,9 +27,7 @@
   50.12              } else {
   50.13                  let theAttributedString = string.attributedSubstring(from: r)
   50.14                  let theString = theAttributedString.string
   50.15 -                if let theStringToAppend = delegate.stringFor(string: theString) {
   50.16 -                    resultString = "\(resultString)\(theStringToAppend)"
   50.17 -                }
   50.18 +                resultString = "\(resultString)\(theString)"
   50.19              }
   50.20          }
   50.21          return resultString