public BaseResource(RawResource obj)
        {
            Type = (BaseResourceType)Enum.Parse(typeof(BaseResourceType), obj.type, true);
            Name = obj.name;

            Path         = new UniversalPath(obj.path ?? string.Empty);
            Size         = new FileSize(string.IsNullOrEmpty(obj.size) ? 0 : Convert.ToUInt64(obj.size));
            ModifiedTime = string.IsNullOrEmpty(obj.date_modified) ? DateTime.MinValue : DateTime.FromFileTime(Convert.ToInt64(obj.date_modified));
            CreatedTime  = string.IsNullOrEmpty(obj.date_created) ? DateTime.MinValue : DateTime.FromFileTime(Convert.ToInt64(obj.date_created));
            Attributes   = obj.attributes ?? string.Empty;
        }
        public async Task DownloadFile(ServerPath serverFileName, LocalFolderRoot root,
                                       CancellationToken token, IProgress <double> progress = null)
        {
            token.ThrowIfCancellationRequested();

            using (var download = await this.client.Files.DownloadAsync(serverFileName.Value))
            {
                var size = download.Response.Size;

                using (var stream = await download.GetContentAsStreamAsync())
                    using (var cipherStreamDecryptor = new CipherStreamDecryptor(stream))
                    {
                        await cipherStreamDecryptor.Init(this.credentials.GetRecepientId(),
                                                         this.credentials.PrivateKey.Data, this.privateKeyPassword);

                        var originalFileName = cipherStreamDecryptor.GetEncryptedValue(OriginalFileNameKey);
                        var fromServerPath   = new UniversalPath(originalFileName);

                        var localPath     = LocalPath.CreateFromUniversal(fromServerPath, root);
                        var tempLocalName = localPath.Value + VirgilTempExtension;

                        var serverWriteTimeUtc = download.Response.ClientModified;
                        var localWriteTimeUtc  = new FileInfo(localPath.Value).LastWriteTimeUtc;

                        if (serverWriteTimeUtc.AlmostEquals(localWriteTimeUtc))
                        {
                            progress?.Report(100);
                            return;
                        }

                        using (OperationExecutionContext.Instance.IgnoreChangesTo(localPath))
                        {
                            var localDir = Path.GetDirectoryName(localPath.Value);
                            if (localDir != null && !Directory.Exists(localDir))
                            {
                                Directory.CreateDirectory(localDir);
                            }

                            try
                            {
                                using (var dest = new FileStream(
                                           tempLocalName, FileMode.Create, FileAccess.ReadWrite,
                                           FileShare.ReadWrite, BufferSize,
                                           FileOptions.Asynchronous | FileOptions.SequentialScan))
                                {
                                    while (cipherStreamDecryptor.HasMore())
                                    {
                                        var chunk = await cipherStreamDecryptor.GetChunk();

                                        await dest.WriteAsync(chunk, 0, chunk.Length, token);

                                        progress?.Report(100.0 * chunk.Length / size);
                                    }

                                    await dest.FlushAsync(token);
                                }

                                //File.Delete(localPath.Value);
                                File.Copy(tempLocalName, localPath.Value, true);
                                File.SetLastWriteTimeUtc(localPath.Value, serverWriteTimeUtc);
                            }
                            finally
                            {
                                try
                                {
                                    File.Delete(tempLocalName);
                                }
                                catch (Exception exception)
                                {
                                    Console.WriteLine(exception);
                                }
                            }
                        }
                    }
            }
        }