diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj
index 011d9e925c5e7af7bfe7267b1abccdb96990ecd1..77e691c65a0fe38f6dd3cfb979976a91a2544c04 100644
--- a/enzevalos_iphone.xcodeproj/project.pbxproj
+++ b/enzevalos_iphone.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		37FE84A92028C40E001B7230 /* AuthStateDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 37FE84A82028C40E001B7230 /* AuthStateDelegate.m */; };
 		3E048C051FAC9ABD00948524 /* HockeySDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E048C041FAC9ABD00948524 /* HockeySDK.swift */; };
 		3E048C061FAC9ABD00948524 /* HockeySDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E048C041FAC9ABD00948524 /* HockeySDK.swift */; };
 		3E6B07DE2011246500E49609 /* invitationText.html in Resources */ = {isa = PBXBuildFile; fileRef = 3E6B07DD2011246500E49609 /* invitationText.html */; };
@@ -19,7 +20,6 @@
 		3E9708B81FAC95F5005825C9 /* PGPKeyID.m in Sources */ = {isa = PBXBuildFile; fileRef = 471BC8E71F960B7C00D64416 /* PGPKeyID.m */; };
 		3E9708B91FAC95F5005825C9 /* NSData+compression.m in Sources */ = {isa = PBXBuildFile; fileRef = 471BC8FE1F960B7C00D64416 /* NSData+compression.m */; };
 		3E9708BA1FAC95F5005825C9 /* TextFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1C3270D1DB907D900CE2ED5 /* TextFormatter.swift */; };
-		3E9708BB1FAC95F5005825C9 /* Providers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F2A5681E85586300320275 /* Providers.swift */; };
 		3E9708BC1FAC95F5005825C9 /* PGPSymmetricallyEncryptedDataPacket.m in Sources */ = {isa = PBXBuildFile; fileRef = 471BC8C81F960B7C00D64416 /* PGPSymmetricallyEncryptedDataPacket.m */; };
 		3E9708BD1FAC95F5005825C9 /* ListViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12041FC1DA409A5002E4940 /* ListViewCell.swift */; };
 		3E9708BE1FAC95F5005825C9 /* PGPUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 471BC8FB1F960B7C00D64416 /* PGPUser.m */; };
@@ -323,7 +323,6 @@
 		A135269C1D955BE000D3BFE1 /* enzevalos_iphoneUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A135269B1D955BE000D3BFE1 /* enzevalos_iphoneUITests.swift */; };
 		A16BA2121E0439B6005E29E3 /* providers.json in Resources */ = {isa = PBXBuildFile; fileRef = A16BA2111E0439B6005E29E3 /* providers.json */; };
 		A17A18F91DDCCF370058D934 /* JakobBode.asc in Resources */ = {isa = PBXBuildFile; fileRef = A17A18F81DDCCF370058D934 /* JakobBode.asc */; };
-		A17FDFF3202C685800F7BA89 /* StudySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17FDFF2202C685800F7BA89 /* StudySettings.swift */; };
 		A18E7D771FBDE5D9002F7CC9 /* LoggingEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A18E7D761FBDE5D9002F7CC9 /* LoggingEventType.swift */; };
 		A19C12471DE602FF007F72E7 /* jabo.asc in Resources */ = {isa = PBXBuildFile; fileRef = A19C12461DE602FF007F72E7 /* jabo.asc */; };
 		A1A9DE731F864B0500B808AA /* ExportCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A9DE721F864B0500B808AA /* ExportCells.swift */; };
@@ -356,7 +355,6 @@
 		A1EB05A01D95696C008659C1 /* MessageBodyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1EB059F1D95696C008659C1 /* MessageBodyTableViewCell.swift */; };
 		A1EB05A41D956E32008659C1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1EB05A31D956E32008659C1 /* Assets.xcassets */; };
 		A1ECE54B1EFBE7ED0009349F /* FolderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1ECE54A1EFBE7ED0009349F /* FolderCell.swift */; };
-		A1F2A5691E85586300320275 /* Providers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F2A5681E85586300320275 /* Providers.swift */; };
 		A1F992291DA7C9100073BF1B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1F9922B1DA7C9100073BF1B /* Main.storyboard */; };
 		A1F992391DA7DD2E0073BF1B /* InboxTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1F9923B1DA7DD2E0073BF1B /* InboxTableViewCell.xib */; };
 		A1FA3F6C1E78565B0093C0B6 /* alice2005-public.gpg in Resources */ = {isa = PBXBuildFile; fileRef = A1FA3F6B1E78565B0093C0B6 /* alice2005-public.gpg */; };
@@ -375,6 +373,9 @@
 		F14D189F1ED880680080515D /* ncpayroll-public.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F14D189B1ED880680080515D /* ncpayroll-public.gpg */; };
 		F14D18A21ED8811F0080515D /* ullimuelle-private.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F14D18A01ED8811F0080515D /* ullimuelle-private.gpg */; };
 		F14D18A31ED8811F0080515D /* ullimuelle-public.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F14D18A11ED8811F0080515D /* ullimuelle-public.gpg */; };
+		F1737ACB2031D7D70000312B /* StudySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17FDFF2202C685800F7BA89 /* StudySettings.swift */; };
+		F1866C86201F707200B72453 /* EmailHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F1866C85201F707200B72453 /* EmailHelper.m */; };
+		F1866CAB2023668F00B72453 /* GTMAppAuthDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1866CAA2023668F00B72453 /* GTMAppAuthDelegate.swift */; };
 		F189C17F1ED59FEF00BAE9B3 /* idsolutions-private.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F189C17D1ED59FEF00BAE9B3 /* idsolutions-private.gpg */; };
 		F189C1801ED59FEF00BAE9B3 /* idsolutions-public.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F189C17E1ED59FEF00BAE9B3 /* idsolutions-public.gpg */; };
 		F18B445E1E7044B70080C041 /* FlipTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = F18B445D1E7044B70080C041 /* FlipTransition.swift */; };
@@ -410,6 +411,8 @@
 
 /* Begin PBXFileReference section */
 		1D4A9E60565DECF52C011BC0 /* Pods-enzevalos_iphone-AdHoc.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphone-AdHoc.release.xcconfig"; path = "../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone-AdHoc/Pods-enzevalos_iphone-AdHoc.release.xcconfig"; sourceTree = "<group>"; };
+		37FE84A82028C40E001B7230 /* AuthStateDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AuthStateDelegate.m; sourceTree = "<group>"; };
+		37FE84AA2028CA63001B7230 /* AuthStateDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AuthStateDelegate.h; sourceTree = "<group>"; };
 		3E048C041FAC9ABD00948524 /* HockeySDK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HockeySDK.swift; sourceTree = "<group>"; };
 		3E6B07DD2011246500E49609 /* invitationText.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = invitationText.html; path = Invitation/invitationText.html; sourceTree = "<group>"; };
 		3E9708AD1FAC925D005825C9 /* enzevalos_iphone.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = enzevalos_iphone.entitlements; sourceTree = "<group>"; };
@@ -667,7 +670,6 @@
 		A1EB059F1D95696C008659C1 /* MessageBodyTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageBodyTableViewCell.swift; sourceTree = "<group>"; };
 		A1EB05A31D956E32008659C1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		A1ECE54A1EFBE7ED0009349F /* FolderCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolderCell.swift; sourceTree = "<group>"; };
-		A1F2A5681E85586300320275 /* Providers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Providers.swift; sourceTree = "<group>"; };
 		A1F992301DA7D22D0073BF1B /* de */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = de; path = de.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
 		A1F992321DA7D2360073BF1B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
 		A1F992341DA7DA570073BF1B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
@@ -696,6 +698,9 @@
 		F14D189B1ED880680080515D /* ncpayroll-public.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "ncpayroll-public.gpg"; path = "keys/ncpayroll-public.gpg"; sourceTree = "<group>"; };
 		F14D18A01ED8811F0080515D /* ullimuelle-private.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "ullimuelle-private.gpg"; path = "keys/ullimuelle-private.gpg"; sourceTree = "<group>"; };
 		F14D18A11ED8811F0080515D /* ullimuelle-public.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "ullimuelle-public.gpg"; path = "keys/ullimuelle-public.gpg"; sourceTree = "<group>"; };
+		F1866C85201F707200B72453 /* EmailHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EmailHelper.m; sourceTree = "<group>"; };
+		F1866C87201F70B700B72453 /* EmailHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EmailHelper.h; sourceTree = "<group>"; };
+		F1866CAA2023668F00B72453 /* GTMAppAuthDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GTMAppAuthDelegate.swift; sourceTree = "<group>"; };
 		F189C17D1ED59FEF00BAE9B3 /* idsolutions-private.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "idsolutions-private.gpg"; path = "keys/idsolutions-private.gpg"; sourceTree = "<group>"; };
 		F189C17E1ED59FEF00BAE9B3 /* idsolutions-public.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "idsolutions-public.gpg"; path = "keys/idsolutions-public.gpg"; sourceTree = "<group>"; };
 		F18B445D1E7044B70080C041 /* FlipTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlipTransition.swift; sourceTree = "<group>"; };
@@ -1146,6 +1151,7 @@
 		A13526771D955BDF00D3BFE1 /* enzevalos_iphone */ = {
 			isa = PBXGroup;
 			children = (
+				F1866C84201F703200B72453 /* OAuth */,
 				3EB4FA9C2012007C001D0625 /* Dialog */,
 				3EC35F1F2003755F008BDF95 /* Invitation */,
 				F1C733331FEC1CAC005A497E /* About */,
@@ -1222,7 +1228,6 @@
 		A18C76851E8185ED00B21414 /* onboarding */ = {
 			isa = PBXGroup;
 			children = (
-				A1F2A5681E85586300320275 /* Providers.swift */,
 				A1083A531E8BFEA6003666B7 /* Onboarding.swift */,
 				A102AA891EDDB4E80024B457 /* videoOnboarding2.m4v */,
 				A1C62E992018F716000E5273 /* OnboardingValueState.swift */,
@@ -1334,6 +1339,18 @@
 			name = inbox;
 			sourceTree = "<group>";
 		};
+		F1866C84201F703200B72453 /* OAuth */ = {
+			isa = PBXGroup;
+			children = (
+				F1866C85201F707200B72453 /* EmailHelper.m */,
+				F1866C87201F70B700B72453 /* EmailHelper.h */,
+				F1866CAA2023668F00B72453 /* GTMAppAuthDelegate.swift */,
+				37FE84AA2028CA63001B7230 /* AuthStateDelegate.h */,
+				37FE84A82028C40E001B7230 /* AuthStateDelegate.m */,
+			);
+			path = OAuth;
+			sourceTree = "<group>";
+		};
 		F1ACF21D1E0C290500C1B843 /* contactView */ = {
 			isa = PBXGroup;
 			children = (
@@ -1628,16 +1645,22 @@
 			);
 			inputPaths = (
 				"${SRCROOT}/../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone/Pods-enzevalos_iphone-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/AppAuth/AppAuth.framework",
 				"${BUILT_PRODUCTS_DIR}/BZipCompression/BZipCompression.framework",
 				"${BUILT_PRODUCTS_DIR}/FrameAccessor/FrameAccessor.framework",
+				"${BUILT_PRODUCTS_DIR}/GTMAppAuth/GTMAppAuth.framework",
+				"${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework",
 				"${BUILT_PRODUCTS_DIR}/KeychainAccess/KeychainAccess.framework",
 				"${BUILT_PRODUCTS_DIR}/Onboard/Onboard.framework",
 				"${BUILT_PRODUCTS_DIR}/VENTokenField/VENTokenField.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppAuth.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BZipCompression.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FrameAccessor.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMAppAuth.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KeychainAccess.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Onboard.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/VENTokenField.framework",
@@ -1716,11 +1739,11 @@
 			);
 			inputPaths = (
 				"${SRCROOT}/../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone/Pods-enzevalos_iphone-resources.sh",
-				$PODS_CONFIGURATION_BUILD_DIR/HockeySDK/HockeySDKResources.bundle,
+				"${PODS_CONFIGURATION_BUILD_DIR}/HockeySDK/HockeySDKResources.bundle",
 			);
 			name = "[CP] Copy Pods Resources";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/HockeySDKResources.bundle",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
@@ -1770,11 +1793,11 @@
 			);
 			inputPaths = (
 				"${SRCROOT}/../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone-AdHoc/Pods-enzevalos_iphone-AdHoc-resources.sh",
-				$PODS_CONFIGURATION_BUILD_DIR/HockeySDK/HockeySDKResources.bundle,
+				"${PODS_CONFIGURATION_BUILD_DIR}/HockeySDK/HockeySDKResources.bundle",
 			);
 			name = "[CP] Copy Pods Resources";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/HockeySDKResources.bundle",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
@@ -1836,16 +1859,22 @@
 			);
 			inputPaths = (
 				"${SRCROOT}/../enzevalos_iphone_workspace/Pods/Target Support Files/Pods-enzevalos_iphone-AdHoc/Pods-enzevalos_iphone-AdHoc-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/AppAuth/AppAuth.framework",
 				"${BUILT_PRODUCTS_DIR}/BZipCompression/BZipCompression.framework",
 				"${BUILT_PRODUCTS_DIR}/FrameAccessor/FrameAccessor.framework",
+				"${BUILT_PRODUCTS_DIR}/GTMAppAuth/GTMAppAuth.framework",
+				"${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework",
 				"${BUILT_PRODUCTS_DIR}/KeychainAccess/KeychainAccess.framework",
 				"${BUILT_PRODUCTS_DIR}/Onboard/Onboard.framework",
 				"${BUILT_PRODUCTS_DIR}/VENTokenField/VENTokenField.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppAuth.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BZipCompression.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FrameAccessor.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMAppAuth.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KeychainAccess.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Onboard.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/VENTokenField.framework",
@@ -1871,7 +1900,6 @@
 				3E9708B81FAC95F5005825C9 /* PGPKeyID.m in Sources */,
 				3E9708B91FAC95F5005825C9 /* NSData+compression.m in Sources */,
 				3E9708BA1FAC95F5005825C9 /* TextFormatter.swift in Sources */,
-				3E9708BB1FAC95F5005825C9 /* Providers.swift in Sources */,
 				3E9708BC1FAC95F5005825C9 /* PGPSymmetricallyEncryptedDataPacket.m in Sources */,
 				3E9708BD1FAC95F5005825C9 /* ListViewCell.swift in Sources */,
 				3E9708BE1FAC95F5005825C9 /* PGPUser.m in Sources */,
@@ -2018,7 +2046,6 @@
 				471BC9281F960B7C00D64416 /* PGPKeyID.m in Sources */,
 				471BC9311F960B7C00D64416 /* NSData+compression.m in Sources */,
 				A1C3270E1DB907D900CE2ED5 /* TextFormatter.swift in Sources */,
-				A1F2A5691E85586300320275 /* Providers.swift in Sources */,
 				471BC91A1F960B7C00D64416 /* PGPSymmetricallyEncryptedDataPacket.m in Sources */,
 				F12041FD1DA409A5002E4940 /* ListViewCell.swift in Sources */,
 				471BC9301F960B7C00D64416 /* PGPUser.m in Sources */,
@@ -2047,6 +2074,7 @@
 				471BC9131F960B7C00D64416 /* PGPPublicSubKeyPacket.m in Sources */,
 				F1984D721E1D327200804E1E /* IconsStyleKit.swift in Sources */,
 				471BC9261F960B7C00D64416 /* PGPKey.m in Sources */,
+				F1737ACB2031D7D70000312B /* StudySettings.swift in Sources */,
 				8428A8691F436A11007649A5 /* UserNameGamificationTableViewCell.swift in Sources */,
 				A114E4321FACB23000E40243 /* StringExtension.swift in Sources */,
 				472F398C1E2519C8009260FB /* CNContactExtension.swift in Sources */,
@@ -2074,7 +2102,7 @@
 				8428A8711F436A1E007649A5 /* GamificationStatusViewController.swift in Sources */,
 				471BC90B1F960B7C00D64416 /* ObjectivePGPObject.m in Sources */,
 				471BC9241F960B7C00D64416 /* PGPFingerprint.m in Sources */,
-				A17FDFF3202C685800F7BA89 /* StudySettings.swift in Sources */,
+				F1866C86201F707200B72453 /* EmailHelper.m in Sources */,
 				471BC9221F960B7C00D64416 /* PGPBigNum.m in Sources */,
 				A10DE4201EFAA2CE005E8189 /* FolderViewController.swift in Sources */,
 				473AC39720054D29006EB8A6 /* NSArray+PGPUtils.m in Sources */,
@@ -2101,6 +2129,7 @@
 				A1EB05A01D95696C008659C1 /* MessageBodyTableViewCell.swift in Sources */,
 				F18B44621E73286C0080C041 /* ReadVENDelegate.swift in Sources */,
 				471BC91E1F960B7C00D64416 /* PGPUserAttributePacket.m in Sources */,
+				F1866CAB2023668F00B72453 /* GTMAppAuthDelegate.swift in Sources */,
 				475B00421F7BB6D6006CDD41 /* PersistentKey+CoreDataClass.swift in Sources */,
 				471BC9161F960B7C00D64416 /* PGPSignaturePacket.m in Sources */,
 				3EC35F2420037651008BDF95 /* InvitationHelper.swift in Sources */,
@@ -2114,6 +2143,7 @@
 				8428A85E1F436A05007649A5 /* CircleView.swift in Sources */,
 				F1C7AC821FED6473007629DB /* AboutViewController.swift in Sources */,
 				472F397C1E1D0B0B009260FB /* PersistentMail +CoreDataProperties.swift in Sources */,
+				37FE84A92028C40E001B7230 /* AuthStateDelegate.m in Sources */,
 				8428A85C1F436A05007649A5 /* ArrowView.swift in Sources */,
 				A1EB05961D956939008659C1 /* InboxTableViewCell.swift in Sources */,
 				A1083A541E8BFEA6003666B7 /* Onboarding.swift in Sources */,
@@ -2462,6 +2492,7 @@
 				CODE_SIGN_ENTITLEMENTS = enzevalos_iphone/PLists/enzevalos_iphone.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEFINES_MODULE = NO;
 				DEVELOPMENT_TEAM = VJ9C93G68Y;
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				INFOPLIST_FILE = "enzevalos_iphone/PLists/enzevalos-Info.plist";
@@ -2514,6 +2545,7 @@
 				CODE_SIGN_ENTITLEMENTS = enzevalos_iphone/PLists/enzevalos_iphone.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEFINES_MODULE = NO;
 				DEVELOPMENT_TEAM = VJ9C93G68Y;
 				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
 				INFOPLIST_FILE = "enzevalos_iphone/PLists/enzevalos-Info.plist";
diff --git a/enzevalos_iphone/AppDelegate.swift b/enzevalos_iphone/AppDelegate.swift
index 95d509fe4211d23d92c0b440c068ac92d8626e82..7bf264b13864a083053ce502d3e0d8a2591b63aa 100644
--- a/enzevalos_iphone/AppDelegate.swift
+++ b/enzevalos_iphone/AppDelegate.swift
@@ -12,6 +12,7 @@ import CoreData
 import Onboard
 import SystemConfiguration
 
+import GTMAppAuth
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -66,16 +67,56 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         return self.orientationLock
     }
     
+    func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
+        if url.absoluteURL.absoluteString.hasPrefix("com.googleusercontent.apps.459157836079-csn0a9p3r8p7q6216fn5u7a6vcum80gn") {
+            if let currentAuthorizationFlow = EmailHelper.singleton().currentAuthorizationFlow {
+                if currentAuthorizationFlow.resumeAuthorizationFlow(with: url) {
+                    EmailHelper.singleton().currentAuthorizationFlow = nil
+                    return true
+                }
+            }
+        }
+        
+        return false
+    }
+    
+    func googleLogin(vc: UIViewController) {
+        if (Onboarding.mailaddress.text?.lowercased() ?? "").contains("gmail") || (Onboarding.mailaddress.text?.lowercased() ?? "").contains("google") {
+            EmailHelper.singleton().doEmailLoginIfRequired(onVC: vc, completionBlock: {
+                guard let userEmail = EmailHelper.singleton().authorization?.userEmail, EmailHelper.singleton().authorization?.canAuthorize() ?? false else {
+                    print("Google authetication failed")
+                    self.credentialsFailed()
+                    return
+                }
+                UserManager.storeUserValue(userEmail as AnyObject, attribute: Attribute.userName)
+                UserManager.storeUserValue(userEmail as AnyObject, attribute: Attribute.userAddr)
+                UserManager.storeUserValue("imap.gmail.com" as AnyObject, attribute: Attribute.imapHostname)
+                UserManager.storeUserValue(993 as AnyObject, attribute: Attribute.imapPort)
+                UserManager.storeUserValue(MCOConnectionType.TLS.rawValue as AnyObject, attribute: Attribute.imapConnectionType)
+                UserManager.storeUserValue(MCOAuthType.xoAuth2.rawValue as AnyObject, attribute: Attribute.imapAuthType)
+                UserManager.storeUserValue("smtp.gmail.com" as AnyObject, attribute: Attribute.smtpHostname)
+                UserManager.storeUserValue(587 as AnyObject, attribute: Attribute.smtpPort)
+                UserManager.storeUserValue(MCOConnectionType.startTLS.rawValue as AnyObject, attribute: Attribute.smtpConnectionType)
+                UserManager.storeUserValue(MCOAuthType.xoAuth2.rawValue as AnyObject, attribute: Attribute.smtpAuthType)
+
+                Onboarding.checkConfig(self.credentialsFailed, work: self.credentialsWork)
+            })
+        }
+    }
+    
     func credentialCheck() {
         self.window?.rootViewController = Onboarding.checkConfigView()
-        if Onboarding.setValues() != OnboardingValueState.fine {
-            credentialsFailed()
+        if Onboarding.googleAuth {
+            Onboarding.googleAuth = false
+            googleLogin(vc: self.window!.rootViewController!)
             return
         }
-        else if !Onboarding.checkConfig(self.credentialsFailed, work: self.credentialsWork) {
-            self.window?.rootViewController = Onboarding.detailOnboarding(self.credentialCheck)
+        if Onboarding.setValues() != OnboardingValueState.fine {
+            credentialsFailed()
             return
         }
+        
+        Onboarding.checkConfig(self.credentialsFailed, work: self.credentialsWork)
     }
 
     func credentialsFailed() {
@@ -110,13 +151,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 
     // Option removed from Settings app, but this might still be usefull in the future
     func resetApp() {
+//         TODO: remove after testing
+//        GTMKeychain.removePasswordFromKeychain(forName: "googleOAuthCodingKey")
+        
         if UserDefaults.standard.bool(forKey: "reset") {
             DataHandler.handler.reset()
             Onboarding.credentials = nil
             Onboarding.credentialFails = 0
             Onboarding.manualSet = false
             UserManager.resetUserValues()
-           
             
             self.window = UIWindow(frame: UIScreen.main.bounds)
             //self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("onboarding")
diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift
index 6905a767cb91abe146d95beb673f9c92166fe1d1..bbfe9bb321992f4e3de94ae6d2d46eddc81c61e6 100644
--- a/enzevalos_iphone/MailHandler.swift
+++ b/enzevalos_iphone/MailHandler.swift
@@ -155,6 +155,13 @@ class MailHandler {
 
     var IMAPIdleSession: MCOIMAPSession?
     var IMAPIdleSupported: Bool?
+    
+    var shouldTryRefreshOAUTH: Bool {
+        get {
+            return (UserManager.loadImapAuthType() == MCOAuthType.xoAuth2 || UserManager.loadSmtpAuthType() == MCOAuthType.xoAuth2) &&
+                !(EmailHelper.singleton().authorization?.authState.isTokenFresh() ?? false)
+        }
+    }
 
     func addAutocryptHeader(_ builder: MCOMessageBuilder) {
         let adr = (UserManager.loadUserValue(Attribute.userAddr) as! String).lowercased()
@@ -251,7 +258,16 @@ class MailHandler {
         builder.addAttachment(keyAttachment)
       
         let sendOperation = session.sendOperation(with: builder.data() , from: userID, recipients: [userID])
-        sendOperation?.start(callback)
+        sendOperation?.start({ error in
+            guard error == nil else {
+                self.retryWithRefreshedOAuth {
+                    self.sendSecretKey(key: key, passcode: passcode, callback: callback)
+                }
+                return
+            }
+            
+            callback(nil)
+        })
         //createSendCopy(sendData: builder.openPGPEncryptedMessageData(withEncryptedData: keyData))
     }
     
@@ -389,6 +405,7 @@ class MailHandler {
         }
     }
 
+    // TODO: add OAuth refresh
     fileprivate func createSendCopy(sendData: Data) {
         let sentFolder = UserManager.backendSentFolderPath
         if !DataHandler.handler.existsFolder(with: sentFolder) {
@@ -404,6 +421,7 @@ class MailHandler {
         }
     }
     
+    // TODO: add OAuth refresh
     fileprivate func createLoggingSendCopy(sendData: Data) {
         let sentFolder = UserManager.loadUserValue(.loggingFolderPath) as! String
         if !DataHandler.handler.existsFolder(with: sentFolder) {
@@ -526,24 +544,24 @@ class MailHandler {
         if let username = UserManager.loadUserValue(Attribute.userAddr) as? String{
             imapsession.username = username
         }
-        if let pw = UserManager.loadUserValue(Attribute.userPW) as? String{
-            imapsession.password = pw
-        }
         //TODO: ERROR HANDLING!
         imapsession.authType = UserManager.loadImapAuthType()
         
+        if UserManager.loadImapAuthType() == MCOAuthType.xoAuth2 {
+            imapsession.oAuth2Token = EmailHelper.singleton().authorization?.authState.lastTokenResponse?.accessToken
+        } else if let pw = UserManager.loadUserValue(Attribute.userPW) as? String {
+            imapsession.password = pw
+        }
+
         if let connType = UserManager.loadUserValue(Attribute.imapConnectionType) as? Int{
             imapsession.connectionType = MCOConnectionType(rawValue: connType)
         }
-        
-        let y = imapsession.folderStatusOperation(INBOX)
-        y?.start{(error, status) -> Void in
-            // TODO: UIDValality check here!
-            let uidValidity = status?.uidValidity
-            let nextId = status?.uidNext
-            let unseencount = status?.unseenCount
-            
-        }
+
+        //TODO @Olli: was this for debug purposes or is there a use for this in production
+//        let y = imapsession.folderStatusOperation(INBOX)
+//        y?.start{(error, status) -> Void in
+//            print("Folder status: \(status.debugDescription)")
+//        }
         
         return imapsession
     }
@@ -555,6 +573,11 @@ class MailHandler {
                 let op = IMAPIdleSession!.idleOperation(withFolder: INBOX, lastKnownUID: UInt32(DataHandler.handler.findFolder(with: INBOX).maxID))
                 op?.start({ error in
                     guard error == nil else {
+                        if self.shouldTryRefreshOAUTH {
+                            self.retryWithRefreshedOAuth {
+                                self.startIMAPIdleIfSupported(addNewMail: addNewMail)
+                            }
+                        }
                         print("An error occured with the idle operation: \(String(describing: error))")
                         return
                     }
@@ -573,6 +596,12 @@ class MailHandler {
         let op = setupIMAPSession().capabilityOperation()
         op?.start({ (error, capabilities) in
             guard error == nil else {
+                if self.shouldTryRefreshOAUTH {
+                    self.retryWithRefreshedOAuth {
+                        self.checkIdleSupport(addNewMail: addNewMail)
+                    }
+                    return
+                }
                 print("Error checking IMAP Idle capabilities: \(String(describing: error))")
                 return
             }
@@ -586,15 +615,23 @@ class MailHandler {
 
     fileprivate func createSMTPSession() -> MCOSMTPSession {
         let session = MCOSMTPSession()
+        session.authType = UserManager.loadSmtpAuthType()
+        if UserManager.loadSmtpAuthType() == MCOAuthType.xoAuth2 {
+            if let lastToken = EmailHelper.singleton().authorization?.authState.lastTokenResponse {
+                session.oAuth2Token = lastToken.accessToken
+            }
+        } else {
+            session.password = UserManager.loadUserValue(Attribute.userPW) as! String
+        }
         session.hostname = UserManager.loadUserValue(Attribute.smtpHostname) as! String
         session.port = UInt32(UserManager.loadUserValue(Attribute.smtpPort) as! Int)
         session.username = UserManager.loadUserValue(Attribute.userAddr) as! String
-        session.password = UserManager.loadUserValue(Attribute.userPW) as! String
         session.authType = UserManager.loadSmtpAuthType()
         session.connectionType = MCOConnectionType(rawValue: UserManager.loadUserValue(Attribute.smtpConnectionType) as! Int)
         return session
     }
 
+    // TODO: add OAuth refresh
     func addFlag(_ uid: UInt64, flags: MCOMessageFlag, folder: String?) {
         var folderName = INBOX
         if let folder = folder{
@@ -625,7 +662,13 @@ class MailHandler {
 
         op?.start { error -> Void in
             if let err = error {
-                print("Error while updating flags: \(err)")
+                if self.shouldTryRefreshOAUTH {
+                    self.retryWithRefreshedOAuth {
+                        self.removeFlag(uid, flags: flags, folder: folder)
+                    }
+                } else {
+                    print("Error while updating flags: \(err)")
+                }
             }
         }
     }
@@ -643,6 +686,12 @@ class MailHandler {
 
             searchOperation.start { (err, indices) -> Void in
                 guard err == nil else {
+                    if self.shouldTryRefreshOAUTH {
+                        self.retryWithRefreshedOAuth {
+                            self.loadMailsForRecord(record, folderPath: folderPath, newMailCallback: newMailCallback, completionCallback: completionCallback)
+                        }
+                        return
+                    }
                     completionCallback(true)
                     return
                 }
@@ -679,6 +728,12 @@ class MailHandler {
         }
         fetchOperation.start { (err, msg, vanished) -> Void in
             guard err == nil else {
+                if self.shouldTryRefreshOAUTH {
+                    self.retryWithRefreshedOAuth {
+                        self.loadMessagesFromServer(uids, folderPath: folderPath, maxLoad: maxLoad, record: record, newMailCallback: newMailCallback, completionCallback: completionCallback)
+                    }
+                    return
+                }
                 print("Error while fetching inbox: \(String(describing: err))")
                 completionCallback(true)
                 return
@@ -952,7 +1007,11 @@ class MailHandler {
         session.hostname = UserManager.loadUserValue(Attribute.smtpHostname) as! String
         session.port = UInt32(UserManager.loadUserValue(Attribute.smtpPort) as! Int)
         session.username = username
-        session.password = UserManager.loadUserValue(Attribute.userPW) as! String
+        if UserManager.loadSmtpAuthType() == MCOAuthType.xoAuth2 {
+            session.oAuth2Token = EmailHelper.singleton().authorization?.authState.lastTokenResponse?.accessToken
+        } else if let pw = UserManager.loadUserValue(Attribute.userPW) as? String {
+            session.password = pw
+        }
         session.authType = UserManager.loadSmtpAuthType()
         session.connectionType = MCOConnectionType.init(rawValue: UserManager.loadUserValue(Attribute.smtpConnectionType) as! Int)
 
@@ -1096,6 +1155,12 @@ class MailHandler {
         
         searchOperation?.start{(err, uids)-> Void in
             guard err == nil else{
+                if self.shouldTryRefreshOAUTH {
+                    self.retryWithRefreshedOAuth {
+                        self.loadMailsSinceDate(folder: folder, since: since, newMailCallback: newMailCallback, completionCallback: completionCallback)
+                    }
+                    return
+                }
                 completionCallback(true)
                 return
             }
@@ -1109,4 +1174,18 @@ class MailHandler {
         }
 
     }
+    
+    func retryWithRefreshedOAuth(completion: @escaping () -> ()) {
+        guard shouldTryRefreshOAUTH else {
+            print("Please only call retryWithRefreshedOAuth after checking shouldTryRefreshOAUTH or your request might be lost.")
+            return
+        }
+        
+        EmailHelper.singleton().checkIfAuthorizationIsValid({authorized in
+            if authorized {
+                self.IMAPSes = nil
+            }
+            completion()
+        })
+    }
 }
diff --git a/enzevalos_iphone/OAuth/AuthStateDelegate.h b/enzevalos_iphone/OAuth/AuthStateDelegate.h
new file mode 100644
index 0000000000000000000000000000000000000000..30abd0d430655f3c649f91663d72a4655ece1b08
--- /dev/null
+++ b/enzevalos_iphone/OAuth/AuthStateDelegate.h
@@ -0,0 +1,17 @@
+//
+//  AuthStateDelegate.h
+//  enzevalos_iphone
+//
+//  Created by joscha1 on 05.02.18.
+//  Copyright © 2018 fu-berlin. All rights reserved.
+//
+
+#ifndef AuthStateDelegate_h
+#define AuthStateDelegate_h
+
+@interface AuthStateDelegate : NSObject <OIDAuthStateChangeDelegate, OIDAuthStateErrorDelegate> {
+
+}
+@end
+
+#endif /* AuthStateDelegate_h */
diff --git a/enzevalos_iphone/OAuth/AuthStateDelegate.m b/enzevalos_iphone/OAuth/AuthStateDelegate.m
new file mode 100644
index 0000000000000000000000000000000000000000..9462e87cdd7274341c7220224ab629373f78f708
--- /dev/null
+++ b/enzevalos_iphone/OAuth/AuthStateDelegate.m
@@ -0,0 +1,35 @@
+//
+//  AuthStateDelegate.m
+//  enzevalos_iphone
+//
+//  Created by joscha1 on 05.02.18.
+//  Copyright © 2018 fu-berlin. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <AppAuth/AppAuth.h>
+#import "AuthStateDelegate.h"
+
+@implementation AuthStateDelegate
+
+- (id)init
+{
+    return [super init];
+}
+
+- (void)didChangeState:(OIDAuthState *)state
+{
+    printf("%s", state.description);
+}
+
+- (void)authState:(OIDAuthState *)state didEncounterAuthorizationError:(NSError *)error
+{
+    printf("%s", error.description);
+}
+
+- (void)authState:(OIDAuthState *)state didEncounterTransientError:(NSError *)error
+{
+    printf("%s", error.description);
+}
+
+@end
diff --git a/enzevalos_iphone/OAuth/EmailHelper.h b/enzevalos_iphone/OAuth/EmailHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..133edca10a1e74b5204eace2efa3f7a7923b377f
--- /dev/null
+++ b/enzevalos_iphone/OAuth/EmailHelper.h
@@ -0,0 +1,24 @@
+//
+//  EmailHelper.h
+//  enzevalos_iphone
+//
+//  Created by Joscha on 29.01.18.
+//  Copyright © 2018 fu-berlin. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <MailCore/MailCore.h>
+#import <AppAuth/AppAuth.h>
+#import <GTMAppAuth/GTMAppAuth.h>
+
+@interface EmailHelper : NSObject
+
++ (EmailHelper *)singleton;
+
+@property(nonatomic, strong, nullable) id<OIDAuthorizationFlowSession> currentAuthorizationFlow;
+@property(nonatomic, nullable) GTMAppAuthFetcherAuthorization *authorization;
+
+- (void)doEmailLoginIfRequiredOnVC:(UIViewController*)vc completionBlock:(dispatch_block_t)completionBlock;
+- (void)checkIfAuthorizationIsValid:(void (^)(BOOL authorized))completionBlock;
+
+@end
diff --git a/enzevalos_iphone/OAuth/EmailHelper.m b/enzevalos_iphone/OAuth/EmailHelper.m
new file mode 100644
index 0000000000000000000000000000000000000000..77f5563142efeaabbdaef57b15a61c3a0486b7f0
--- /dev/null
+++ b/enzevalos_iphone/OAuth/EmailHelper.m
@@ -0,0 +1,197 @@
+//
+//  EmailHelper.m
+//  enzevalos_iphone
+//
+//  Created by Joscha on 29.01.18.
+//  Copyright © 2018 fu-berlin. All rights reserved.
+//
+
+#import "EmailHelper.h"
+#import <GTMSessionFetcher/GTMSessionFetcherService.h>
+#import <GTMSessionFetcher/GTMSessionFetcher.h>
+//#import "enzevalos_iphone-Swift.h"
+
+/*! @brief The OIDC issuer from which the configuration will be discovered.
+ */
+static NSString *const kIssuer = @"https://accounts.google.com";
+
+/*! @brief The OAuth client ID.
+ @discussion For Google, register your client at
+ https://console.developers.google.com/apis/credentials?project=_
+ The client should be registered with the "iOS" type.
+ */
+static NSString *const kClientID = @"459157836079-csn0a9p3r8p7q6216fn5u7a6vcum80gn.apps.googleusercontent.com";
+
+/*! @brief The OAuth redirect URI for the client @c kClientID.
+ @discussion With Google, the scheme of the redirect URI is the reverse DNS notation of the
+ client ID. This scheme must be registered as a scheme in the project's Info
+ property list ("CFBundleURLTypes" plist key). Any path component will work, we use
+ 'oauthredirect' here to help disambiguate from any other use of this scheme.
+ */
+static NSString *const kRedirectURI =
+@"com.googleusercontent.apps.459157836079-csn0a9p3r8p7q6216fn5u7a6vcum80gn:/oauthredirect";
+
+/*! @brief @c NSCoding key for the authState property. You don't need to change this value.
+ */
+static NSString *const kExampleAuthorizerKey = @"googleOAuthCodingKey";
+
+@interface EmailHelper ()   <OIDAuthStateChangeDelegate,
+                            OIDAuthStateErrorDelegate>
+@end
+
+@implementation EmailHelper
+
+static dispatch_once_t pred;
+static EmailHelper *shared = nil;
+
++ (EmailHelper *)singleton {
+    dispatch_once(&pred, ^{ shared = [[EmailHelper alloc] init]; });
+    return shared;
+}
+
+- (instancetype)init {
+    if (self = [super init]) {
+        [self loadState];
+    }
+    return self;
+}
+
+#pragma mark -
+
+// CALL THIS TO START
+- (void)doEmailLoginIfRequiredOnVC:(UIViewController*)vc completionBlock:(dispatch_block_t)completionBlock {
+    // Optional: if no internet connectivity, do nothing
+//    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
+    if (true) { // TODO: we nee to check for internet conectivity here
+        dispatch_async(dispatch_get_main_queue(), ^{
+            
+            // first see if we already have authorization
+            [self checkIfAuthorizationIsValid:^(BOOL authorized) {
+                NSAssert([NSThread currentThread].isMainThread, @"ERROR MAIN THREAD NEEDED");
+                if (authorized) {
+                    if (completionBlock)
+                    completionBlock();
+                } else {
+                    [self doInitialAuthorizationWithVC:vc completionBlock:completionBlock];
+                }
+            }];
+        });
+    };
+}
+
+/*! @brief Saves the @c GTMAppAuthFetcherAuthorization to @c NSUSerDefaults.
+ */
+- (void)saveState {
+    if (_authorization.canAuthorize) {
+        [GTMAppAuthFetcherAuthorization saveAuthorization:_authorization toKeychainForName:kExampleAuthorizerKey];
+    } else {
+        NSLog(@"EmailHelper: WARNING, attempt to save a google authorization which cannot authorize, discarding");
+        [GTMAppAuthFetcherAuthorization removeAuthorizationFromKeychainForName:kExampleAuthorizerKey];
+    }
+}
+
+/*! @brief Loads the @c GTMAppAuthFetcherAuthorization from @c NSUSerDefaults.
+ */
+- (void)loadState {
+    GTMAppAuthFetcherAuthorization* authorization =
+    [GTMAppAuthFetcherAuthorization authorizationFromKeychainForName:kExampleAuthorizerKey];
+    
+    if (authorization.canAuthorize) {
+        self.authorization = authorization;
+        self.authorization.authState.stateChangeDelegate = self;
+        self.authorization.authState.errorDelegate = self;
+    } else {
+        NSLog(@"EmailHelper: WARNING, loaded google authorization cannot authorize, discarding");
+        [GTMAppAuthFetcherAuthorization removeAuthorizationFromKeychainForName:kExampleAuthorizerKey];
+    }
+    
+    
+}
+
+- (void)doInitialAuthorizationWithVC:(UIViewController*)vc completionBlock:(dispatch_block_t)completionBlock {
+    NSURL *issuer = [NSURL URLWithString:kIssuer];
+    NSURL *redirectURI = [NSURL URLWithString:kRedirectURI];
+    
+    NSLog(@"EmailHelper: Fetching configuration for issuer: %@", issuer);
+    
+    // discovers endpoints
+    [OIDAuthorizationService discoverServiceConfigurationForIssuer:issuer completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
+        if (!configuration) {
+            NSLog(@"EmailHelper: Error retrieving discovery document: %@", [error localizedDescription]);
+            self.authorization = nil;
+            return;
+        }
+        
+        NSLog(@"EmailHelper: Got configuration: %@", configuration);
+        
+        // builds authentication request
+        OIDAuthorizationRequest *request =
+        [[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
+                                                      clientId:kClientID
+                                                        scopes:@[OIDScopeOpenID, OIDScopeProfile, OIDScopeEmail, @"https://mail.google.com/"]
+                                                   redirectURL:redirectURI
+                                                  responseType:OIDResponseTypeCode
+                                          additionalParameters:nil];
+        // performs authentication request
+        NSLog(@"EmailHelper: Initiating authorization request with scope: %@", request.scope);
+        self.currentAuthorizationFlow = [OIDAuthState authStateByPresentingAuthorizationRequest:request presentingViewController:vc callback:^(OIDAuthState *_Nullable authState, NSError *_Nullable error) {
+            if (authState) {
+                self.authorization = [[GTMAppAuthFetcherAuthorization alloc] initWithAuthState:authState];
+                NSLog(@"EmailHelper: Got authorization tokens. Access token: %@", authState.lastTokenResponse.accessToken);
+                [self saveState];
+            } else {
+                self.authorization = nil;
+                NSLog(@"EmailHelper: Authorization error: %@", [error localizedDescription]);
+            }
+            if (completionBlock)
+            dispatch_async(dispatch_get_main_queue(), completionBlock);
+        }];
+    }];
+}
+
+// Performs a UserInfo request to the account to see if the token works
+- (void)checkIfAuthorizationIsValid:(void (^)(BOOL authorized))completionBlock {
+    NSLog(@"EmailHelper: Performing userinfo request");
+    
+    // Creates a GTMSessionFetcherService with the authorization.
+    // Normally you would save this service object and re-use it for all REST API calls.
+    GTMSessionFetcherService *fetcherService = [[GTMSessionFetcherService alloc] init];
+    fetcherService.authorizer = self.authorization;
+    
+    // Creates a fetcher for the API call.
+    NSURL *userinfoEndpoint = [NSURL URLWithString:@"https://www.googleapis.com/oauth2/v3/userinfo"];
+    GTMSessionFetcher *fetcher = [fetcherService fetcherWithURL:userinfoEndpoint];
+    [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
+        // Checks for an error.
+        if (error) {
+            // OIDOAuthTokenErrorDomain indicates an issue with the authorization.
+            if ([error.domain isEqual:OIDOAuthTokenErrorDomain]) {
+                [GTMAppAuthFetcherAuthorization removeAuthorizationFromKeychainForName:kExampleAuthorizerKey];
+                self.authorization = nil;
+                NSLog(@"EmailHelper: Authorization error during token refresh, cleared state. %@", error);
+                if (completionBlock)
+                completionBlock(NO);
+            } else {
+                // Other errors are assumed transient.
+                NSLog(@"EmailHelper: Transient error during token refresh. %@", error);
+                if (completionBlock)
+                completionBlock(NO);
+            }
+            return;
+        }
+        
+        NSLog(@"EmailHelper: authorization is valid");
+        if (completionBlock)
+        completionBlock(YES);
+    }];
+}
+
+- (void)didChangeState:(nonnull OIDAuthState *)state {
+    [self saveState];
+}
+
+- (void)authState:(nonnull OIDAuthState *)state didEncounterAuthorizationError:(nonnull NSError *)error {
+    NSLog(@"Received authorization error: %@", error);
+}
+
+@end
diff --git a/enzevalos_iphone/OAuth/GTMAppAuthDelegate.swift b/enzevalos_iphone/OAuth/GTMAppAuthDelegate.swift
new file mode 100644
index 0000000000000000000000000000000000000000..f5c987fa820ee735629b835b811be26a720b1ebd
--- /dev/null
+++ b/enzevalos_iphone/OAuth/GTMAppAuthDelegate.swift
@@ -0,0 +1,19 @@
+//
+//  GTMAppAuthDelegate.swift
+//  enzevalos_iphone
+//
+//  Created by Joscha on 01.02.18.
+//  Copyright © 2018 fu-berlin. All rights reserved.
+//
+
+import Foundation
+
+class GTMAppAuthDelegate: NSObject, OIDAuthStateChangeDelegate, OIDAuthStateErrorDelegate {
+    func didChange(_ state: OIDAuthState) {
+        print("State: \(state)")
+    }
+    
+    func authState(_ state: OIDAuthState, didEncounterAuthorizationError error: Error) {
+        print("AuthState: \(state); Error: \(error)")
+    }
+}
diff --git a/enzevalos_iphone/Onboarding.swift b/enzevalos_iphone/Onboarding.swift
index 2dc989a0b9a9eaa6417519f5659b1c127a0f25a5..28bf7100e119145c5a86fb74101d79e7a57d5d41 100644
--- a/enzevalos_iphone/Onboarding.swift
+++ b/enzevalos_iphone/Onboarding.swift
@@ -21,6 +21,7 @@ class Onboarding: NSObject {
     static var mailaddress = UITextField.init()
     static var username = UITextField.init()
     static var password = UITextField.init()
+    static var googleButton = UIBarButtonItem.init()
     static var credentials: UIView? = nil
     static var imapServer = UITextField.init()
     static var smtpServer = UITextField.init()
@@ -36,6 +37,9 @@ class Onboarding: NSObject {
     static var smtpTransDataDelegate = PickerDataDelegate.init(rows: ["a", "b", "c"])
     static var background = UIImage.init()
     static var manualSet = false
+    static var googleAuth = false
+    
+    static var loginViewController: UIViewController?
 
     static let font = UIFont.init(name: "Helvetica-Light", size: 28)
     static let padding: CGFloat = 30
@@ -150,9 +154,13 @@ class Onboarding: NSObject {
             keyboardToolbar.sizeToFit()
             keyboardToolbar.barTintColor = defaultColor
             keyboardToolbar.backgroundColor = defaultColor
+            let googleBarButton = UIBarButtonItem(title: "Login with Google", style: .plain, target: self, action: #selector(oauth))
+            googleBarButton.tintColor = .orange
+            googleButton = googleBarButton
             let flexBarButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
             let doneBarButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.dismissKeyboard))
-            keyboardToolbar.items = [flexBarButton, doneBarButton]
+            doneBarButton.tintColor = .orange
+            keyboardToolbar.items = [googleBarButton, flexBarButton, doneBarButton]
             mailaddress.inputAccessoryView = keyboardToolbar
             password.inputAccessoryView = keyboardToolbar
 
@@ -205,9 +213,15 @@ class Onboarding: NSObject {
             })
         }
 
+        loginViewController = vc!
         return vc!
     }
 
+    static func oauth() {
+        googleAuth = true
+        doWhenDone()
+    }
+    
     static func dismissKeyboard() {
         mailaddress.endEditing(true)
         password.endEditing(true)
@@ -472,11 +486,10 @@ class Onboarding: NSObject {
         AppDelegate.getAppDelegate().requestForAccess(callback)
     }
 
-    static func checkConfig(_ fail: @escaping () -> (), work: @escaping () -> ()) -> Bool {
+    static func checkConfig(_ fail: @escaping () -> (), work: @escaping () -> ()) {
         self.work = work
         self.fail = fail
         AppDelegate.getAppDelegate().mailHandler.checkIMAP(imapCompletion)
-        return true
     }
 
     static func imapCompletion(_ error: Error?) { //FIXME: vorher NSError? Mit Error? immer noch gültig?
@@ -509,8 +522,7 @@ class Onboarding: NSObject {
             //TODO: REMOVE BEFORE STUDY
             loadTestAcc()
             return setServerValues(mailaddress: mailAddress)
-        }
-        else {
+        } else {
             UserManager.storeUserValue(imapServer.text as AnyObject?, attribute: Attribute.imapHostname)
             UserManager.storeUserValue(Int(imapPort.text ?? "143") as AnyObject?, attribute: Attribute.imapPort)
             UserManager.storeUserValue(smtpServer.text as AnyObject?, attribute: Attribute.smtpHostname)
@@ -535,9 +547,10 @@ class Onboarding: NSObject {
 
         if let provider = manager.provider(forEmail: mailaddress), let imap = (provider.imapServices() as? [MCONetService]), imap != [], let smtp = (provider.smtpServices() as? [MCONetService]), smtp != [] {
             let imapService = imap[0]
-            UserManager.storeUserValue((imapService.info()["hostname"] ?? "imap.web.de") as AnyObject?, attribute: Attribute.imapHostname)
+            UserManager.storeUserValue((imapService.info()["hostname"] ?? "imap.web.de") as AnyObject?, attribute: Attribute.imapHostname) //TODO @jakob: web.de?!?
             UserManager.storeUserValue((imapService.info()["port"] ?? 587) as AnyObject?, attribute: Attribute.imapPort)
-
+            
+            print(imapService.info())
             if let trans = imapService.info()["ssl"] as? Bool, trans {
                 UserManager.storeUserValue(MCOConnectionType.TLS.rawValue as AnyObject?, attribute: Attribute.imapConnectionType)
             } else if let trans = imapService.info()["starttls"] as? Bool, trans {
@@ -660,9 +673,6 @@ class Onboarding: NSObject {
 
 class TextFieldDelegate: NSObject, UITextFieldDelegate {
 
-    func textFieldDidBeginEditing(_ textField: UITextField) {
-    }
-
     func textFieldShouldReturn(_ textField: UITextField) -> Bool {
         if textField == Onboarding.mailaddress {
             textField.resignFirstResponder()
diff --git a/enzevalos_iphone/PLists/enzevalos-Info.plist b/enzevalos_iphone/PLists/enzevalos-Info.plist
index 89a2df6f53a03a018de1c4d69c80dbf42a58955b..a90c9e33caf8d0f6c5c391d40e5abccfc9863a92 100644
--- a/enzevalos_iphone/PLists/enzevalos-Info.plist
+++ b/enzevalos_iphone/PLists/enzevalos-Info.plist
@@ -2,6 +2,17 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>com.googleusercontent.apps.459157836079-csn0a9p3r8p7q6216fn5u7a6vcum80gn</string>
+			</array>
+		</dict>
+	</array>
 	<key>CFBundleDevelopmentRegion</key>
 	<string>en</string>
 	<key>CFBundleDisplayName</key>
diff --git a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift
index ad47853b4e5748a271253464495f6bedda8d56be..9bc60cad37d6219edd208670a6f21227ddd32888 100644
--- a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift	
+++ b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift	
@@ -127,7 +127,11 @@ extension PersistentMail {
             self.willAccessValue(forKey: "from")
             let text = (self.primitiveValue(forKey: "from") as? Mail_Address)
             self.didAccessValue(forKey: "from")
-            return text!
+            if let text = text {
+                return text
+            }
+            print("We have a nil")
+            return Mail_Address()
         }
     }
     public var containsSecretKey: Bool{
diff --git a/enzevalos_iphone/Providers.swift b/enzevalos_iphone/Providers.swift
deleted file mode 100644
index f833a4ecf68fb65591f77318bcb8e645e2fc7cc8..0000000000000000000000000000000000000000
--- a/enzevalos_iphone/Providers.swift
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-//  Providers.swift
-//  enzevalos_iphone
-//
-//  Created by jakobsbode on 24.03.17.
-//  Copyright © 2017 fu-berlin. All rights reserved.
-//
-
-enum Provider : String {
-    case WEB = "web.de", FU = "fu-berlin.de", ZEDAT = "zedat.fu-berlin.de", ENZEVALOS = "enzevalos.de"
-}
-
-class Providers {
-    static let config: [Provider : [Attribute : AnyObject?]] = createConfig()
-    
-    static func createConfig() -> [Provider : [Attribute : AnyObject?]] {
-        var config: [Provider : [Attribute : AnyObject?]] = [:]
-        config.updateValue([.smtpHostname : "smtp.web.de" as AnyObject?, .smtpPort : 587 as AnyObject?, .imapHostname : "imap.web.de" as AnyObject?, .imapPort : 993 as AnyObject?, .imapConnectionType: MCOConnectionType.TLS.rawValue as AnyObject?, .imapAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?, .smtpConnectionType: MCOConnectionType.startTLS.rawValue as AnyObject?, .smtpAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?], forKey: Provider.WEB)
-        config.updateValue([.smtpHostname : "mail.zedat.fu-berlin.de" as AnyObject?, .smtpPort : 587 as AnyObject?, .imapHostname : "mail.zedat.fu-berlin.de" as AnyObject?, .imapPort : 993 as AnyObject?, .imapConnectionType: MCOConnectionType.TLS.rawValue as AnyObject?, .imapAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?, .smtpConnectionType: MCOConnectionType.startTLS.rawValue as AnyObject?, .smtpAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?], forKey: Provider.FU)
-        config.updateValue([.smtpHostname : "mail.zedat.fu-berlin.de" as AnyObject?, .smtpPort : 587 as AnyObject?, .imapHostname : "mail.zedat.fu-berlin.de" as AnyObject?, .imapPort : 143 as AnyObject?, .imapConnectionType: MCOConnectionType.startTLS.rawValue as AnyObject?, .imapAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?, .smtpConnectionType: MCOConnectionType.TLS.rawValue as AnyObject?, .smtpAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?], forKey: Provider.ZEDAT)
-        config.updateValue([.smtpHostname : "mail.enzevalos.de" as AnyObject?, .smtpPort : 465 as AnyObject?, .imapHostname : "mail.enzevalos.de" as AnyObject?, .imapPort : 993 as AnyObject?, .imapConnectionType: MCOConnectionType.TLS.rawValue as AnyObject?, .imapAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?, .smtpConnectionType: MCOConnectionType.TLS.rawValue as AnyObject?, .smtpAuthType: MCOAuthType.saslPlain.rawValue as AnyObject?], forKey: Provider.ENZEVALOS)
-        return config
-    }
-    
-    static func setValues(_ provider: Provider) {
-        for key in (config[provider]?.keys)! {
-            UserManager.storeUserValue(config[provider]![key]!, attribute: key)
-        }
-    }
-}
diff --git a/enzevalos_iphone/SendViewController.swift b/enzevalos_iphone/SendViewController.swift
index 73927b52674ab04ff27b8514fdd0f1002acc3717..4a867d73a860d68db7d7061f52059165d74d43ea 100644
--- a/enzevalos_iphone/SendViewController.swift
+++ b/enzevalos_iphone/SendViewController.swift
@@ -472,6 +472,11 @@ class SendViewController: UIViewController {
 
     func mailSend(_ error: Error?) {
         if (error != nil) {
+            if AppDelegate.getAppDelegate().mailHandler.shouldTryRefreshOAUTH {
+                AppDelegate.getAppDelegate().mailHandler.retryWithRefreshedOAuth { [weak self] in
+                    self?.pressSend(nil)
+                }
+            }
             NSLog("Error sending email: \(String(describing: error))")
             //            AppDelegate.getAppDelegate().showMessage("An error occured", completion: nil) @jakob: wofür ist dieses showMessage aus AppDelegate gut?
             let alert = UIAlertController(title: NSLocalizedString("ReceiveError", comment: "There was an error"), message: NSLocalizedString("ErrorText", comment: ""), preferredStyle: UIAlertControllerStyle.alert)
@@ -647,7 +652,7 @@ class SendViewController: UIViewController {
         }
     }
 
-    @IBAction func pressSend(_ sender: AnyObject) {
+    @IBAction func pressSend(_ sender: AnyObject?) {
         let toEntrys = toText.mailTokens
         let ccEntrys = ccText.mailTokens
         let subject = subjectText.inputText()!
diff --git a/enzevalos_iphone/de.lproj/Localizable.strings b/enzevalos_iphone/de.lproj/Localizable.strings
index 0f8b96dec60c037c8e1aa331c5bbb403ed4ec060..d0517d8ba45940f088dc61b529270c84f3c227fd 100644
--- a/enzevalos_iphone/de.lproj/Localizable.strings
+++ b/enzevalos_iphone/de.lproj/Localizable.strings
@@ -175,3 +175,4 @@
 "copyKey" = "Schloss in Zwischenablage kopieren";
 "NeverUpdated" = "Fehler bei Aktualisierung";
 
+
diff --git a/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h b/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h
index 0f6044831b2f42643b7553cda169005795a93e1b..e046e5bcd01782905829e32f4da6a1b4e92800c8 100644
--- a/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h
+++ b/enzevalos_iphone/enzevalos_iphone-Bridging-Header.h
@@ -11,3 +11,7 @@
 #import <Onboard/OnboardingContentViewController.h>
 #import "ObjectivePGP/ObjectivePGP.h"
 #import <CommonCrypto/CommonHMAC.h>
+#import <AppAuth/AppAuth.h>
+#import <GTMAppAuth/GTMAppAuth.h>
+#import <GTMSessionFetcher/GTMSessionFetcher.h>
+#import "OAuth/EmailHelper.h"