/// <summary>
        /// Copy files from the download cache to the desired installation state
        /// </summary>
        /// <remarks>Precondition: all files must already exist in the cache</remarks>
        protected async Task <ILibraryOperationResult> WriteToFilesAsync(ILibraryInstallationState state, CancellationToken cancellationToken)
        {
            if (state.Files != null)
            {
                try
                {
                    foreach (string file in state.Files)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(LibraryOperationResult.FromCancelled(state));
                        }

                        if (string.IsNullOrEmpty(file))
                        {
                            string id = LibraryNamingScheme.GetLibraryId(state.Name, state.Version);
                            return(new LibraryOperationResult(state, PredefinedErrors.FileNameMustNotBeEmpty(id)));
                        }

                        string sourcePath      = GetCachedFileLocalPath(state, file);
                        string destinationPath = Path.Combine(state.DestinationPath, file);
                        bool   writeOk         = await HostInteraction.CopyFileAsync(sourcePath, destinationPath, cancellationToken);

                        if (!writeOk)
                        {
                            return(new LibraryOperationResult(state, PredefinedErrors.CouldNotWriteFile(file)));
                        }
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    return(new LibraryOperationResult(state, PredefinedErrors.PathOutsideWorkingDirectory()));
                }
                catch (Exception ex)
                {
                    HostInteraction.Logger.Log(ex.ToString(), LogLevel.Error);
                    return(new LibraryOperationResult(state, PredefinedErrors.UnknownException()));
                }
            }

            return(LibraryOperationResult.FromSuccess(state));
        }