/// <summary>
        ///     See <see cref="ITransformer.ExecuteAsync()" />.
        /// </summary>
        public Task ExecuteAsync()
        {
            // Make sure this transformation has not been started already
            if (_hasStarted)
            {
                throw new InvalidOperationException("This transformation has already been started.");
            }

            // Record the start of this transformation
            _hasStarted = true;

            // If there is a dependent transformer then start it
            var dependentTask = _dependentTransformer?.ExecuteAsync();

            // Create the task that we will complete when this transformation is complete
            var taskCompletionSource = new TaskCompletionSource <object>();

            // Create the arguments for the process function
            var args = new Tuple <TaskCompletionSource <object>, Task>(taskCompletionSource, dependentTask);

            // Start all the work items for this process
            for (var i = 0; i < ThreadCount; ++i)
            {
                ThreadPool.QueueUserWorkItem(Process, args);
            }

            // Return the wait handle
            return(taskCompletionSource.Task);
        }