/// <summary>
        /// Begins an asynchronous operation to delete a table.
        /// </summary>
        /// <param name="tableName">The table name.</param>
        /// <param name="callback">The callback delegate that will receive notification when the asynchronous operation completes.</param>
        /// <param name="state">A user-defined object that will be passed to the callback delegate.</param>
        /// <returns>
        /// An <see cref="IAsyncResult"/> that references the asynchronous request.
        /// </returns>
        public IAsyncResult BeginDeleteTable(string tableName, AsyncCallback callback, object state)
        {
            CommonUtils.CheckStringParameter(tableName, false, "tableName", Protocol.Constants.TableServiceMaxStringPropertySizeInChars);
            TableServiceUtilities.CheckTableName(tableName, "tableName");

            return(TaskImplHelper.BeginImplWithRetry(() => this.DeleteTableImpl(tableName), RetryPolicy, callback, state));
        }
        /// <summary>
        /// Begins an asynchronous operation to delete the tables if it exists.
        /// </summary>
        /// <param name="tableName">The table name.</param>
        /// <param name="callback">The callback delegate that will receive notification when the asynchronous operation completes.</param>
        /// <param name="state">A user-defined object that will be passed to the callback delegate.</param>
        /// <returns>An <see cref="IAsyncResult"/> that references the asynchronous operation.</returns>
        public IAsyncResult BeginDeleteTableIfExist(string tableName, AsyncCallback callback, object state)
        {
            CommonUtils.CheckStringParameter(tableName, false, "tableName", Protocol.Constants.TableServiceMaxStringPropertySizeInChars);

            TableServiceUtilities.CheckTableName(tableName, "tableName");

            return(TaskImplHelper.BeginImpl <bool>((setResult) => this.DeleteTableIfExistImpl(tableName, setResult), callback, state));
        }
        /// <summary>
        /// Creates the tables needed for the specified service context.
        /// </summary>
        /// <param name="serviceContextType">The type of service context.</param>
        /// <param name="baseAddress">The Table service endpoint to use to create the client.</param>
        /// <param name="credentials">The account credentials.</param>
        public static void CreateTablesFromModel(Type serviceContextType, string baseAddress, StorageCredentials credentials)
        {
            var client = new CloudTableClient(baseAddress, credentials);

            foreach (var table in TableServiceUtilities.EnumerateEntitySetNames(serviceContextType))
            {
                client.CreateTableIfNotExist(table);
            }
        }
        /// <summary>
        /// Verifies whether the table exist implementation.
        /// </summary>
        /// <param name="tableName">The table name.</param>
        /// <param name="setResult">The set result.</param>
        /// <returns>A sequence of tasks to do the operation.</returns>
        private TaskSequence DoesTableExistImpl(string tableName, Action <bool> setResult)
        {
            CommonUtils.CheckStringParameter(tableName, false, "tableName", Protocol.Constants.TableServiceMaxStringPropertySizeInChars);
            TableServiceUtilities.CheckTableName(tableName, "tableName");

            var svc = this.GetDataServiceContext();

            var tableExistsQuery = (from table in svc.CreateQuery <TableServiceTable>(Protocol.Constants.TableServiceTablesName)
                                    where table.TableName == tableName
                                    select table).AsTableServiceQuery();

            ResultSegment <TableServiceTable> segment = null;

            while (true)
            {
                Task <ResultSegment <TableServiceTable> > tableExistsSegmentTask;

                if (segment == null)
                {
                    tableExistsSegmentTask = TaskImplHelper.GetRetryableAsyncTask <ResultSegment <TableServiceTable> >(
                        (setResultInner) => tableExistsQuery.ExecuteSegmentedImpl(null, setResultInner), RetryPolicy);
                }
                else
                {
                    tableExistsSegmentTask = TaskImplHelper.GetRetryableAsyncTask <ResultSegment <TableServiceTable> >(segment.GetNextImpl, RetryPolicy);
                }

                yield return(tableExistsSegmentTask);

                if (GetResultOrDefault(tableExistsSegmentTask, out segment))
                {
                    if (segment.Results.Any())
                    {
                        setResult(true);

                        break;
                    }
                    else
                    {
                        setResult(false);

                        break;
                    }
                }
                else
                {
                    setResult(false);

                    break;
                }
            }
        }
        /// <summary>
        /// Creates the table if not exist implementation.
        /// </summary>
        /// <param name="tableName">The table name.</param>
        /// <param name="setResult">The set result.</param>
        /// <returns>A sequence of tasks to do the operation.</returns>
        private TaskSequence CreateTableIfNotExistImpl(string tableName, Action <bool> setResult)
        {
            CommonUtils.CheckStringParameter(tableName, false, "tableName", Protocol.Constants.TableServiceMaxStringPropertySizeInChars);
            TableServiceUtilities.CheckTableName(tableName, "tableName");

            var doesTableExistTask = new InvokeTaskSequenceTask <bool>((set) => this.DoesTableExistImpl(tableName, set));

            yield return(doesTableExistTask);

            if (doesTableExistTask.Result)
            {
                setResult(false);
            }
            else
            {
                var createTableTask = TaskImplHelper.GetRetryableAsyncTask <InvalidOperationException>((resultSetter) => this.CreateTableImpl(tableName, resultSetter), RetryPolicy);

                yield return(createTableTask);

                // wrap any exceptions
                try
                {
                    if (createTableTask.Result == null)
                    {
                        setResult(true);
                    }
                    else
                    {
                        StorageClientException exception = Utilities.TranslateDataServiceClientException(createTableTask.Result) as StorageClientException;
                        if (exception != null &&
                            exception.ErrorCode == StorageErrorCode.ResourceAlreadyExists &&
                            exception.ExtendedErrorInformation != null &&
                            exception.ExtendedErrorInformation.ErrorCode == TableErrorCodeStrings.TableAlreadyExists)
                        {
                            setResult(false);
                        }
                        else
                        {
                            throw createTableTask.Result;
                        }
                    }
                }
                catch (InvalidOperationException ex)
                {
                    throw Utilities.TranslateDataServiceClientException(ex);
                }
            }
        }