/**
   * Reserved for internal use. Execute this table operation on the specified table, using the
   * specified {@link TableRequestOptions} and {@link OperationContext}.
   *
   * <p>This method will invoke the Storage Service REST API to execute this table operation, using
   * the Table service endpoint and storage account credentials in the {@link CloudTableClient}
   * object.
   *
   * @param client A {@link CloudTableClient} instance specifying the Table service endpoint,
   *     storage account credentials, and any additional query parameters.
   * @param tableName A <code>String</code> containing the name of the table.
   * @param options A {@link TableRequestOptions} object that specifies execution options such as
   *     retry policy and timeout settings for the operation.
   * @param opContext An {@link OperationContext} object for tracking the current operation.
   * @return A {@link TableResult} containing the results of executing the operation.
   * @throws StorageException if an error occurs in the storage operation.
   */
  protected TableResult execute(
      final CloudTableClient client,
      final String tableName,
      TableRequestOptions options,
      OperationContext opContext)
      throws StorageException {
    if (opContext == null) {
      opContext = new OperationContext();
    }

    if (options == null) {
      options = new TableRequestOptions();
    }

    opContext.initialize();
    options.applyDefaults(client);
    Utility.assertNotNullOrEmpty("TableName", tableName);

    if (this.getOperationType() == TableOperationType.INSERT
        || this.getOperationType() == TableOperationType.INSERT_OR_MERGE
        || this.getOperationType() == TableOperationType.INSERT_OR_REPLACE) {
      return this.performInsert(client, tableName, options, opContext);
    } else if (this.getOperationType() == TableOperationType.DELETE) {
      return this.performDelete(client, tableName, options, opContext);
    } else if (this.getOperationType() == TableOperationType.MERGE) {
      return this.performMerge(client, tableName, options, opContext);
    } else if (this.getOperationType() == TableOperationType.REPLACE) {
      return this.performUpdate(client, tableName, options, opContext);
    } else if (this.getOperationType() == TableOperationType.RETRIEVE) {
      return ((QueryTableOperation) this).performRetrieve(client, tableName, options, opContext);
    } else {
      throw new IllegalArgumentException("Unknown table operation");
    }
  }
  /**
   * Gets a result segment of an iterable collection of queues whose names begin with the specified
   * prefix for this queue, using the specified listing details options, request options, and
   * operation context.
   *
   * @param prefix A <code>String</code> that represents the prefix of the queue name to match.
   * @param detailsIncluded A {@link QueueListingDetails} value that indicates whether queue
   *     metadata will be returned.
   * @param maxResults The maximum number of queue results to retrieve.
   * @param continuationToken A {@link ResultContinuation} object that represents a continuation
   *     token returned by a previous listing operation.
   * @param options A {@link QueueRequestOptions} object that specifies any additional options for
   *     the request. Specifying <code>null</code> will use the default request options from the
   *     associated service client ( {@link CloudQueue}).
   * @param opContext An {@link OperationContext} object that represents the context for the current
   *     operation. This object is used to track requests to the storage service, and to provide
   *     additional runtime information about the operation.
   * @return A {@link ResultSegment} of {@link CloudQueue} objects that contains a segment of the
   *     iterable collection of {@link CloudQueue} objects that represent the requested queues in
   *     the storage service.
   * @throws StorageException If a storage service error occurred during the operation.
   */
  @DoesServiceRequest
  public ResultSegment<CloudQueue> listQueuesSegmented(
      final String prefix,
      final QueueListingDetails detailsIncluded,
      final int maxResults,
      final ResultContinuation continuationToken,
      QueueRequestOptions options,
      OperationContext opContext)
      throws StorageException {

    if (opContext == null) {
      opContext = new OperationContext();
    }

    if (options == null) {
      options = new QueueRequestOptions();
    }

    opContext.initialize();
    options.applyDefaults(this);

    Utility.assertContinuationType(continuationToken, ResultContinuationType.QUEUE);

    final StorageOperation<CloudQueueClient, Void, ResultSegment<CloudQueue>> impl =
        new StorageOperation<CloudQueueClient, Void, ResultSegment<CloudQueue>>(options) {
          @Override
          public ResultSegment<CloudQueue> execute(
              final CloudQueueClient client, final Void dontCare, final OperationContext opContext)
              throws Exception {
            return CloudQueueClient.this.listQueuesCore(
                prefix,
                detailsIncluded,
                maxResults,
                continuationToken,
                this.getRequestOptions(),
                this,
                opContext);
          }
        };

    return ExecutionEngine.executeWithRetry(
        this, null, impl, options.getRetryPolicyFactory(), opContext);
  }
  /**
   * Returns an iterable collection of queues whose names begin with the specified prefix for this
   * Queue service client, using the specified details setting, request options, and operation
   * context.
   *
   * @param prefix A <code>String</code> that represents the queue name prefix.
   * @param detailsIncluded A {@link QueueListingDetails} value that indicates whether queue
   *     metadata will be returned.
   * @param options A {@link QueueRequestOptions} object that specifies any additional options for
   *     the request. Specifying <code>null</code> will use the default request options from the
   *     associated service client ( {@link CloudQueue}).
   * @param opContext An {@link OperationContext} object that represents the context for the current
   *     operation. This object is used to track requests to the storage service, and to provide
   *     additional runtime information about the operation.
   * @return An iterable collection of {@link CloudQueue} objects that represents the specified
   *     queues for this client.
   */
  @DoesServiceRequest
  public Iterable<CloudQueue> listQueues(
      final String prefix,
      final QueueListingDetails detailsIncluded,
      QueueRequestOptions options,
      OperationContext opContext) {
    if (opContext == null) {
      opContext = new OperationContext();
    }

    if (options == null) {
      options = new QueueRequestOptions();
    }

    opContext.initialize();
    options.applyDefaults(this);

    final SegmentedStorageOperation<CloudQueueClient, Void, ResultSegment<CloudQueue>> impl =
        new SegmentedStorageOperation<CloudQueueClient, Void, ResultSegment<CloudQueue>>(
            options, null) {
          @Override
          public ResultSegment<CloudQueue> execute(
              final CloudQueueClient client, final Void dontCare, final OperationContext opContext)
              throws Exception {

            final ResultSegment<CloudQueue> result =
                CloudQueueClient.this.listQueuesCore(
                    prefix,
                    detailsIncluded,
                    -1,
                    this.getToken(),
                    this.getRequestOptions(),
                    this,
                    opContext);

            this.setToken(result.getContinuationToken());
            return result;
          }
        };

    return new LazySegmentedIterable<CloudQueueClient, Void, CloudQueue>(
        impl, this, null, options.getRetryPolicyFactory(), opContext);
  }