public async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            await Task.Yield();

            this.CreateDestinationDirectory(cancellationToken);

            var enumerator = this.transferEnumerator.EnumerateLocation(cancellationToken).GetEnumerator();

            while (true)
            {
                if (!enumerator.MoveNext())
                {
                    break;
                }

                TransferEntry entry      = enumerator.Current;
                ErrorEntry    errorEntry = entry as ErrorEntry;
                if (errorEntry != null)
                {
                    TransferException exception = errorEntry.Exception as TransferException;
                    if (null != exception)
                    {
                        throw exception;
                    }
                    else
                    {
                        throw new TransferException(
                                  TransferErrorCode.FailToEnumerateDirectory,
                                  errorEntry.Exception.GetExceptionMessage(),
                                  errorEntry.Exception);
                    }
                }

                if (entry.IsDirectory)
                {
                    this.baseDirectoryTransfer.AddSubDir(entry.RelativePath, () =>
                    {
                        var currentContinuationToken                 = new SerializableListContinuationToken(entry.ContinuationToken);
                        currentContinuationToken.Journal             = this.enumerateContinuationToken.Journal;
                        currentContinuationToken.StreamJournalOffset = this.enumerateContinuationToken.StreamJournalOffset;
                        this.enumerateContinuationToken              = currentContinuationToken;
                        return(this.enumerateContinuationToken);
                    });
                }
                else
                {
                    SingleObjectTransfer transferItem = this.baseDirectoryTransfer.CreateTransfer(entry);
#if DEBUG
                    Utils.HandleFaultInjection(entry.RelativePath, transferItem);
#endif

                    this.CreateDestinationParentDirectoryRecursively(transferItem);

                    this.baseDirectoryTransfer.AddSingleObjectTransfer(transferItem, () =>
                    {
                        var currentContinuationToken                 = new SerializableListContinuationToken(entry.ContinuationToken);
                        currentContinuationToken.Journal             = this.enumerateContinuationToken.Journal;
                        currentContinuationToken.StreamJournalOffset = this.enumerateContinuationToken.StreamJournalOffset;
                        this.enumerateContinuationToken              = currentContinuationToken;
                        return(this.enumerateContinuationToken);
                    });
                }
            }
        }
        private void ListNewTransfers(CancellationToken cancellationToken)
        {
            // list new transfers
            if (this.enumerateContinuationToken != null)
            {
                this.SourceEnumerator.EnumerateContinuationToken = this.enumerateContinuationToken.ListContinuationToken;
            }

            ShouldTransferCallbackAsync shouldTransferCallback = this.DirectoryContext?.ShouldTransferCallbackAsync;

            try
            {
                var enumerator = this.SourceEnumerator.EnumerateLocation(cancellationToken).GetEnumerator();

                while (true)
                {
                    Utils.CheckCancellation(cancellationToken);

                    if (!enumerator.MoveNext())
                    {
                        break;
                    }

                    TransferEntry entry      = enumerator.Current;
                    ErrorEntry    errorEntry = entry as ErrorEntry;
                    if (errorEntry != null)
                    {
                        TransferException exception = errorEntry.Exception as TransferException;
                        if (null != exception)
                        {
                            throw exception;
                        }
                        else
                        {
                            throw new TransferException(
                                      TransferErrorCode.FailToEnumerateDirectory,
                                      errorEntry.Exception.GetExceptionMessage(),
                                      errorEntry.Exception);
                        }
                    }

                    this.shouldTransferQueue.EnqueueJob(async() =>
                    {
                        try
                        {
                            SingleObjectTransfer candidate = this.CreateTransfer(entry);

                            bool shouldTransfer = shouldTransferCallback == null || await shouldTransferCallback(candidate.Source.Instance, candidate.Destination.Instance);

                            return(new Tuple <SingleObjectTransfer, TransferEntry>(shouldTransfer ? candidate : null, entry));
                        }
                        catch (Exception ex)
                        {
                            throw new TransferException(TransferErrorCode.FailToEnumerateDirectory, string.Format(CultureInfo.CurrentCulture, "Error happens when handling entry {0}: {1}", entry.ToString(), ex.Message), ex);
                        }
                    });
                }
            }
            finally
            {
                this.shouldTransferQueue.CompleteAdding();
            }
        }