//
    // Download
    //

    public bool DownloadAssets(List <string> keys, ProgressCallback pg, DownloadCompleteCallback dl)
    {
        // Download the assets in the list and all their dependencies.

        if (running)
        {
            return(false);
        }
        running = true;

        dlProgressCallback = pg;
        dlCompleteCallback = dl;
        progressBase       = -1f;

        downloadHandle            = Addressables.DownloadDependenciesAsync(keys.ToArray(), Addressables.MergeMode.Union);
        downloadHandle.Completed += DownloadComplete;

        // Start coroutine for progress. Don't use coroutines for anything that can throw
        // an exception (which includes downloading unchecked keys), because it can't be trapped.
        // See https://www.jacksondunstan.com/articles/3718

        StartCoroutine(DownloadProgress());

        return(true);
    }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="uploadProgressCallback">Upload progress call back delegate.</param>
        /// <param name="downloadProgressCallback">Download progress call back delegate.</param>
        /// <param name="uploadCompleteCallback">Upload complete call back delegate.</param>
        /// <param name="downloadCompleteCallback">Download complete call back delegate.</param>
        /// <param name="onCommandError">On error delegate event handler.</param>
        /// <param name="onAsyncThreadError">On async thread error delegate event handler.</param>
        /// <param name="credentials">The user credentials.</param>
        /// <param name="connection">The server connection data.</param>
        /// <param name="filePath">The file path transfer data.</param>
        /// <param name="internalFilePath">The internal file path transfer data.</param>
        /// <param name="operation">The current operation.</param>
        /// <param name="secureConnection">Is the connection secure.</param>
        /// <param name="timeout">The time out for the operation.</param>
        public FileTransferDataChannel(
            UploadProgressCallback uploadProgressCallback, DownloadProgressCallback downloadProgressCallback,
            UploadCompleteCallback uploadCompleteCallback, DownloadCompleteCallback downloadCompleteCallback,
            ClientCommandHandler onCommandError, ClientThreadErrorHandler onAsyncThreadError,
            NetworkCredential credentials, FileTransferConnection connection, FileTransferPath filePath,
            FileTransferPath internalFilePath, Operation operation, bool secureConnection, int timeout)
        {
            _connection      = new FileTransferConnection();
            _connection.Host = connection.Host;
            _connection.Port = connection.Port;
            _connection.ValidateCertificate = false;
            _connection.UseDataChannel      = false;

            _secureConnection = secureConnection;
            _credentials      = credentials;
            _filePath         = filePath;
            _operation        = operation;
            _timeout          = timeout;

            _internalFilePath = internalFilePath;

            _onCommandError     = onCommandError;
            _onAsyncThreadError = onAsyncThreadError;

            _uploadProgressCallback   = uploadProgressCallback;
            _downloadProgressCallback = downloadProgressCallback;
            _uploadCompleteCallback   = uploadCompleteCallback;
            _downloadCompleteCallback = downloadCompleteCallback;
        }