ews_config_lookup_worker_run (EConfigLookupWorker *lookup_worker,
			      EConfigLookup *config_lookup,
			      const ENamedParameters *params,
			      ENamedParameters **out_restart_params,
			      GCancellable *cancellable,
			      GError **error)
{
	CamelEwsSettings *ews_settings = NULL;
	ESource *source;
	const gchar *email_address;
	const gchar *password;
	const gchar *extension_name;

	g_return_if_fail (E_IS_EWS_CONFIG_LOOKUP (lookup_worker));
	g_return_if_fail (E_IS_CONFIG_LOOKUP (config_lookup));
	g_return_if_fail (params != NULL);

	email_address = e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_EMAIL_ADDRESS);

	if (!email_address || !*email_address)
		return;

	if (!e_named_parameters_exists (params, E_CONFIG_LOOKUP_PARAM_PASSWORD)) {
		g_set_error (error, E_CONFIG_LOOKUP_WORKER_ERROR, E_CONFIG_LOOKUP_WORKER_ERROR_REQUIRES_PASSWORD,
			_("Requires user password to continue"));
		return;
	}

	ews_settings = g_object_new (CAMEL_TYPE_EWS_SETTINGS, NULL);
	camel_ews_settings_set_email (ews_settings, email_address);

	extension_name = e_source_camel_get_extension_name ("ews");
	source = e_config_lookup_get_source (config_lookup, E_CONFIG_LOOKUP_SOURCE_COLLECTION);
	if (source && e_source_has_extension (source, extension_name)) {
		ESourceCamel *camel_extension;
		CamelSettings *settings;

		camel_extension = e_source_get_extension (source, extension_name);
		settings = e_source_camel_get_settings (camel_extension);

		/* Copy only the host url */
		if (CAMEL_IS_EWS_SETTINGS (settings))
			camel_ews_settings_set_hosturl (ews_settings, camel_ews_settings_get_hosturl (CAMEL_EWS_SETTINGS (settings)));
	}

	password = e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_PASSWORD);

	if (password) {
		const gchar *servers;
		gchar *certificate_host = NULL;
		gchar *certificate_pem = NULL;
		GTlsCertificateFlags certificate_errors = 0;
		GError *local_error = NULL;

		if (e_named_parameters_exists (params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_PEM) &&
		    e_named_parameters_exists (params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_TRUST) &&
		    e_named_parameters_exists (params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_HOST)) {
			GTlsCertificate *certificate;
			const gchar *param_certificate_pem;

			param_certificate_pem = e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_PEM);
			certificate = g_tls_certificate_new_from_pem (param_certificate_pem, -1, NULL);

			if (certificate) {
				ETrustPromptResponse trust_response;

				trust_response = e_config_lookup_decode_certificate_trust (
					e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_TRUST));

				if (trust_response != E_TRUST_PROMPT_RESPONSE_UNKNOWN) {
					ESourceWebdav *webdav_extension;

					webdav_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);
					e_source_webdav_update_ssl_trust (webdav_extension,
						e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_HOST),
						certificate, trust_response);
				}

				g_object_unref (certificate);
			}
		}

		if (e_ews_autodiscover_ws_url_sync (source, ews_settings, email_address, password, &certificate_pem, &certificate_errors, cancellable, &local_error)) {
			ews_config_lookup_worker_result_from_settings (lookup_worker, config_lookup, email_address, ews_settings, params);
		} else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
			const gchar *hosturl;
			SoupURI *suri;

			hosturl = camel_ews_settings_get_hosturl (ews_settings);
			suri = soup_uri_new (hosturl);
			if (suri) {
				certificate_host = g_strdup (soup_uri_get_host (suri));

				soup_uri_free (suri);
			}
		} else {
			g_clear_error (&local_error);
		}

		servers = e_named_parameters_get (params, E_CONFIG_LOOKUP_PARAM_SERVERS);

		if (servers && *servers) {
			gchar **servers_strv;
			gint ii;

			servers_strv = g_strsplit (servers, ";", 0);

			for (ii = 0; servers_strv && servers_strv[ii] && !g_cancellable_is_cancelled (cancellable) && !local_error; ii++) {
				const gchar *server = servers_strv[ii];
				gchar *tmp = NULL;

				if (*server && !strstr (server, "://")) {
					tmp = g_strconcat ("https://", server, "/EWS/Exchange.asmx", NULL);
					server = tmp;
				}

				camel_ews_settings_set_hosturl (ews_settings, server);

				if (e_ews_autodiscover_ws_url_sync (source, ews_settings, email_address, password, &certificate_pem, &certificate_errors, cancellable, &local_error)) {
					ews_config_lookup_worker_result_from_settings (lookup_worker, config_lookup, email_address, ews_settings, params);
				} else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
					const gchar *hosturl;
					SoupURI *suri;

					hosturl = camel_ews_settings_get_hosturl (ews_settings);
					suri = soup_uri_new (hosturl);
					if (suri) {
						certificate_host = g_strdup (soup_uri_get_host (suri));

						soup_uri_free (suri);
					}
				} else {
					g_clear_error (&local_error);
				}

				g_free (tmp);
			}

			g_strfreev (servers_strv);
		}

		if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) &&
		    certificate_pem && *certificate_pem && certificate_errors) {
			gchar *description = e_trust_prompt_describe_certificate_errors (certificate_errors);

			if (description) {
				g_set_error_literal (error, E_CONFIG_LOOKUP_WORKER_ERROR,
					E_CONFIG_LOOKUP_WORKER_ERROR_CERTIFICATE, description);

				g_free (description);

				if (out_restart_params) {
					if (!*out_restart_params)
						*out_restart_params = e_named_parameters_new_clone (params);

					e_named_parameters_set (*out_restart_params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_PEM, certificate_pem);
					e_named_parameters_set (*out_restart_params, E_CONFIG_LOOKUP_PARAM_CERTIFICATE_HOST, certificate_host);
				}
			}
		}

		g_clear_error (&local_error);
		g_free (certificate_host);
		g_free (certificate_pem);

		if (out_restart_params && !*out_restart_params)
			*out_restart_params = e_named_parameters_new_clone (params);
	}

	g_clear_object (&ews_settings);
}