/// <summary>
        /// Create intersection with another option
        /// </summary>
        /// <param name="option"></param>
        /// <returns>this if <paramref name="option"/> is null or new instance with intersection</returns>
        public virtual AllOptions Intersection(IOption option)
        {
            if (option == null)
            {
                return(this);
            }
            AllOptions result = new AllOptions();

            result.CanBrowse           = this.CanBrowse | option.CanBrowse();
            result.CanGetEntry         = this.CanGetEntry | option.CanGetEntry();
            result.CanObserve          = this.CanObserve | option.CanObserve();
            result.CanOpen             = this.CanOpen | option.CanOpen();
            result.CanRead             = this.CanRead | option.CanRead();
            result.CanWrite            = this.CanWrite | option.CanWrite();
            result.CanCreateFile       = this.CanCreateFile | option.CanCreateFile();
            result.CanDelete           = this.CanDelete | option.CanDelete();
            result.CanSetFileAttribute = this.CanSetFileAttribute | option.CanSetFileAttribute();
            result.CanMount            = this.CanMount | option.CanMount();
            result.CanCreateFile       = this.CanCreateFile | option.CanCreateFile();
            result.CanDelete           = this.CanDelete | option.CanDelete();
            result.CanMove             = this.CanMove | option.CanMove();
            result.CanCreateDirectory  = this.CanCreateDirectory | option.CanCreateDirectory();
            result.CanMount            = this.CanMount | option.CanMount();
            result.CanUnmount          = this.CanUnmount | option.CanUnmount();
            result.CanListMountPoints  = this.CanListMountPoints | option.CanListMountPoints();
            result.SubPath             = this.SubPath ?? option.SubPath();
            return(result);
        }
        /// <summary>
        /// Delete resource at <paramref name="uri"/>.
        ///
        /// <paramref name="recurse"/> is ignored..
        ///
        /// Authentication header can be placed in <paramref name="option"/> as instance of <see cref="AuthenticationHeaderValue"/> wrapped in (for example) <see cref="Token"/> or <see cref="TokenList"/>.
        ///
        /// Other <see cref="HttpHeaders"/> can also placed in <paramref name="option"/>.
        ///
        /// <see cref="CancellationToken"/> can be placed in <paramref name="option"/>.
        /// </summary>
        /// <param name="uri">path to a file or directory</param>
        /// <param name="recurse">value is ignored</param>
        /// <param name="option">(optional) operation specific option; capability constraint, a session, security token or credential. Used for authenticating, authorizing or restricting the operation.</param>
        /// <exception cref="FileNotFoundException">The specified path is invalid.</exception>
        /// <exception cref="IOException">On unexpected IO error, or if <paramref name="uri"/> refered to a directory that wasn't empty and <paramref name="recurse"/> is false, or trying to delete root when not allowed</exception>
        /// <exception cref="ArgumentNullException"><paramref name="uri"/> is null</exception>
        /// <exception cref="ArgumentException"><paramref name="uri"/> contains invalid characters</exception>
        /// <exception cref="NotSupportedException">The <see cref="IFileSystem"/> doesn't support deleting files</exception>
        /// <exception cref="UnauthorizedAccessException">The access requested is not permitted by the operating system for the specified path, such as when access is Write or ReadWrite and the file or directory is set for read-only access.</exception>
        /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters.</exception>
        /// <exception cref="InvalidOperationException"><paramref name="uri"/> refers to non-file device</exception>
        /// <exception cref="ObjectDisposedException"/>
        public async Task DeleteAsync(string uri, bool recurse = false, IOption option = null)
        {
            // Take reference
            var _httpClient = httpClient;

            // Assert not disposed
            if (_httpClient == null || IsDisposing)
            {
                throw new ObjectDisposedException(nameof(HttpFileSystem));
            }
            // Assert allowed
            if (!options.CanDelete || !option.CanDelete(true))
            {
                throw new NotSupportedException(nameof(DeleteAsync));
            }
            // Append subpath
            string _subpath = option.SubPath() ?? this.options.SubPath;

            if (_subpath != null)
            {
                uri = _subpath + uri;
            }

            // Cancel token
            CancellationToken cancel = default;

            option.TryGetToken(uri, out cancel);

            try
            {
                // Request object
                using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, uri))
                {
                    // Read token
                    ReadTokenToHeaders(uri, option, request.Headers);
                    // Read authentication token
                    AuthenticationHeaderValue authenticationHeader;
                    if (this.token.TryGetToken(uri, out authenticationHeader) || option.TryGetToken(uri, out authenticationHeader))
                    {
                        request.Headers.Authorization = authenticationHeader;
                    }

                    // Start DELETE
                    HttpResponseMessage response = await _httpClient.SendAsync(request);

                    // Assert ok
                    if (!response.IsSuccessStatusCode)
                    {
                        throw new FileSystemException(this, uri, response.ReasonPhrase);
                    }
                }
            }
            catch (Exception e) when(e is FileSystemException == false)
            {
                throw new FileSystemException(this, uri, e.Message, e);
            }
        }
 /// <summary>
 /// Read options from <paramref name="option"/> and return flattened object.
 /// </summary>
 /// <param name="option"></param>
 /// <returns></returns>
 public virtual void ReadFrom(IOption option)
 {
     this.CanBrowse           = option.CanBrowse();
     this.CanGetEntry         = option.CanGetEntry();
     this.CanObserve          = option.CanObserve();
     this.CanOpen             = option.CanOpen();
     this.CanRead             = option.CanRead();
     this.CanWrite            = option.CanWrite();
     this.CanCreateFile       = option.CanCreateFile();
     this.CanDelete           = option.CanDelete();
     this.CanMove             = option.CanMove();
     this.CanCreateDirectory  = option.CanCreateDirectory();
     this.CanMount            = option.CanMount();
     this.CanUnmount          = option.CanUnmount();
     this.CanListMountPoints  = option.CanListMountPoints();
     this.SubPath             = option.SubPath();
     this.CanSetFileAttribute = option.CanSetFileAttribute();
 }