public static bool IsOnline (ProxyOptions proxyOptions)
 {
   if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
   {
     // Use NCSI to detect network status according to https://technet.microsoft.com/en-us/library/ee126135(v=WS.10).aspx
     // try DNS first
     try
     {
       IPHostEntry hostEntry = Dns.GetHostEntry ("dns.msftncsi.com");
       IPAddress ipAddress = Array.Find (hostEntry.AddressList, ip => ip.AddressFamily == AddressFamily.InterNetwork);
       if (ipAddress != null && ipAddress.ToString() == "131.107.255.255") return true;
     }
     catch (Exception) {}
     // if DNS failed, try to download the ncsi.txt
     try
     {
       string txt;
       using (var client = new WebClient())
       {
         IWebProxy proxy = (proxyOptions != null) ? SynchronizerFactory.CreateProxy (proxyOptions) : null;
         client.Proxy = proxy;
         txt = client.DownloadString (new Uri ("http://www.msftncsi.com/ncsi.txt"));
       }
       if (txt != "Microsoft NCSI") return false;
       return true;
     }
     catch (Exception)
     {
       return false;
     }
   }
   else
     return false;
 }
    public AdvancedOptions (bool closeConnectionAfterEachRequest, ProxyOptions proxyOptions)
    {
      if (proxyOptions == null)
        throw new ArgumentNullException ("proxyOptions");

      _closeConnectionAfterEachRequest = closeConnectionAfterEachRequest;
      _proxyOptions = proxyOptions;
    }
    public AdvancedOptions (bool closeConnectionAfterEachRequest, ProxyOptions proxyOptions, MappingConfigurationBase mappingConfiguration)
    {
      if (proxyOptions == null)
        throw new ArgumentNullException ("proxyOptions");

      _closeConnectionAfterEachRequest = closeConnectionAfterEachRequest;
      _proxyOptions = proxyOptions;
      _mappingConfiguration = mappingConfiguration;
    }
    public void UpdateOptions (Options options, bool checkIfOnline)
    {
      _pendingOutlookItems.Clear();
      _fullSyncPending = false;

      _profileName = options.Name;
      _profileId = options.Id;
      _proxyOptions = options.ProxyOptions;
      _synchronizer = _synchronizerFactory.CreateSynchronizer (options);
      _interval = TimeSpan.FromMinutes (options.SynchronizationIntervalInMinutes);
      _inactive = options.Inactive;
      _changeTriggeredSynchronizationEnabled = options.EnableChangeTriggeredSynchronization;
      _checkIfOnline = checkIfOnline;
    }
    public async Task UpdateOptions (Options options, GeneralOptions generalOptions)
    {
      if (options == null)
        throw new ArgumentNullException (nameof (options));
      if (generalOptions == null)
        throw new ArgumentNullException (nameof (generalOptions));

      _pendingOutlookItems.Clear();
      _fullSyncPending = false;

      _profileName = options.Name;
      _profileId = options.Id;
      _proxyOptions = options.ProxyOptions;
      _synchronizer = options.Inactive ? NullOutlookSynchronizer.Instance : await _synchronizerFactory.CreateSynchronizer (options, generalOptions);
      _interval = TimeSpan.FromMinutes (options.SynchronizationIntervalInMinutes);
      _inactive = options.Inactive;
      _checkIfOnline = generalOptions.CheckIfOnline;

      if (_folderChangeWatcher != null)
      {
        _folderChangeWatcher.ItemSavedOrDeleted -= FolderChangeWatcher_ItemSavedOrDeleted;
        _folderChangeWatcher.Dispose();
        _folderChangeWatcher = null;
      }

      if (!_inactive && options.EnableChangeTriggeredSynchronization)
      {
        _folderChangeWatcher =
            _folderChangeWatcherFactory.Create (options.OutlookFolderEntryId, options.OutlookFolderStoreId);
        _folderChangeWatcher.ItemSavedOrDeleted += FolderChangeWatcher_ItemSavedOrDeleted;
      }
    }
    private static IWebProxy CreateProxy (ProxyOptions proxyOptions)
    {
      IWebProxy proxy = null;

      if (proxyOptions.ProxyUseDefault)
      {
        proxy = WebRequest.DefaultWebProxy;
        proxy.Credentials = CredentialCache.DefaultCredentials;
      }
      else if (proxyOptions.ProxyUseManual)
      {
        proxy = new WebProxy (proxyOptions.ProxyUrl, false);
        if (!string.IsNullOrEmpty (proxyOptions.ProxyUserName))
        {
          proxy.Credentials = new NetworkCredential (proxyOptions.ProxyUserName, proxyOptions.ProxyPassword);
        }
        else
        {
          proxy.Credentials = CredentialCache.DefaultCredentials;
        }
      }
      return proxy;
    }
    private static async Task<HttpClient> CreateHttpClient (string username, string password, TimeSpan calDavConnectTimeout, ServerAdapterType serverAdapterType, ProxyOptions proxyOptions)
    {
      IWebProxy proxy = CreateProxy (proxyOptions);

      switch (serverAdapterType)
      {
        case ServerAdapterType.Default:
          var httpClientHandler = new HttpClientHandler();
          if (!string.IsNullOrEmpty (username))
          {
            httpClientHandler.Credentials = new NetworkCredential (username, password);
            httpClientHandler.AllowAutoRedirect = false;
          }
          httpClientHandler.Proxy = proxy;
          httpClientHandler.UseProxy = (proxy != null);

          var httpClient = new HttpClient (httpClientHandler);
          httpClient.Timeout = calDavConnectTimeout;
          return httpClient;
        case ServerAdapterType.GoogleOAuth:
          return await OAuth.Google.GoogleHttpClientFactory.CreateHttpClient (username, GetProductWithVersion(), proxy);
        default:
          throw new ArgumentOutOfRangeException ("serverAdapterType");
      }
    }
    public static IWebDavClient CreateWebDavClient (
        string username,
        string password,
        TimeSpan timeout,
        ServerAdapterType serverAdapterType,
        bool closeConnectionAfterEachRequest,
        ProxyOptions proxyOptions
        )
    {
      switch (serverAdapterType)
      {
        case ServerAdapterType.Default:
        case ServerAdapterType.GoogleOAuth:
          var productAndVersion = GetProductAndVersion();
          return new DataAccess.HttpClientBasedClient.WebDavClient (
              () => CreateHttpClient (username, password, timeout, serverAdapterType, proxyOptions),
              productAndVersion.Item1,
              productAndVersion.Item2,
              closeConnectionAfterEachRequest);

        case ServerAdapterType.SynchronousWebRequestBased:
          return new DataAccess.WebRequestBasedClient.WebDavClient (
              username, password, timeout, timeout);
        default:
          throw new ArgumentOutOfRangeException ("serverAdapterType");
      }
    }