private Dictionary<string, List<Dictionary<string, AttributeValue>>> GetAttributeItems(bool isAsync)
        {
            var allItems = new Dictionary<string, List<Dictionary<string, AttributeValue>>>();
            if (Batches == null || Batches.Count == 0)
                return allItems;

            DocumentBatchGet firstBatch = this.Batches[0];
            BatchGetItemRequest request = new BatchGetItemRequest();
            request.BeforeRequestEvent += isAsync ?
                new RequestEventHandler(firstBatch.TargetTable.UserAgentRequestEventHandlerAsync) :
                new RequestEventHandler(firstBatch.TargetTable.UserAgentRequestEventHandlerSync);

            foreach (var batch in Batches)
            {
                if (batch.Keys != null && batch.Keys.Count > 0)
                {
                    if (request.RequestItems.ContainsKey(batch.TargetTable.TableName))
                    {
                        throw new InvalidOperationException("Multiple batches refer to the same table.");
                    }

                    request.RequestItems.Add(
                        batch.TargetTable.TableName,
                        new KeysAndAttributes
                        {
                            Keys = batch.Keys,
                            AttributesToGet = batch.AttributesToGet,
                            ConsistentRead = batch.ConsistentRead
                        });
                }
            }
            var client = firstBatch.TargetTable.DDBClient;

            do
            {
                var batchGetItemResponse = client.BatchGetItem(request);
                var result = batchGetItemResponse.BatchGetItemResult;

                var responses = result.Responses;
                foreach (var response in responses)
                {
                    string tableName = response.Key;
                    BatchResponse batchResponse = response.Value;
                    List<Dictionary<string, AttributeValue>> items = batchResponse.Items;

                    List<Dictionary<string, AttributeValue>> fetchedItems;
                    if (!allItems.TryGetValue(tableName, out fetchedItems))
                    {
                        fetchedItems = new List<Dictionary<string, AttributeValue>>();
                        allItems[tableName] = fetchedItems;
                    }
                    fetchedItems.AddRange(items);
                }

                request.RequestItems = result.UnprocessedKeys;
            } while (request.RequestItems.Count > 0);

            return allItems;
        }
 IAsyncResult invokeBatchGetItem(BatchGetItemRequest batchGetItemRequest, AsyncCallback callback, object state, bool synchronized)
 {
     IRequest irequest = new BatchGetItemRequestMarshaller().Marshall(batchGetItemRequest);
     var unmarshaller = BatchGetItemResponseUnmarshaller.GetInstance();
     AsyncResult result = new AsyncResult(irequest, callback, state, synchronized, signer, unmarshaller);
     Invoke(result);
     return result;
 }
 /// <summary>
 /// <para>Retrieves the attributes for multiple items from multiple tables using their primary keys.</para> <para>The maximum number of item
 /// attributes that can be retrieved for a single operation is 100. Also, the number of items retrieved is constrained by a 1 MB the size limit.
 /// If the response size limit is exceeded or a partial result is returned due to an internal processing failure, Amazon DynamoDB returns an
 /// <c>UnprocessedKeys</c> value so you can retry the operation starting with the next item to get.</para> <para>Amazon DynamoDB automatically
 /// adjusts the number of items returned per page to enforce this limit. For example, even if you ask to retrieve 100 items, but each individual
 /// item is 50k in size, the system returns 20 items and an appropriate <c>UnprocessedKeys</c> value so you can get the next page of results. If
 /// necessary, your application needs its own logic to assemble the pages of results into one set.</para>
 /// </summary>
 /// 
 /// <param name="batchGetItemRequest">Container for the necessary parameters to execute the BatchGetItem service method on
 ///          AmazonDynamoDB.</param>
 /// 
 /// <returns>The response from the BatchGetItem service method, as returned by AmazonDynamoDB.</returns>
 /// 
 /// <exception cref="ProvisionedThroughputExceededException"/>
 /// <exception cref="InternalServerErrorException"/>
 /// <exception cref="ResourceNotFoundException"/>
 public BatchGetItemResponse BatchGetItem(BatchGetItemRequest batchGetItemRequest)
 {
     IAsyncResult asyncResult = invokeBatchGetItem(batchGetItemRequest, null, null, true);
     return EndBatchGetItem(asyncResult);
 }
 /// <summary>
 /// Initiates the asynchronous execution of the BatchGetItem operation.
 /// <seealso cref="Amazon.DynamoDB.AmazonDynamoDB.BatchGetItem"/>
 /// </summary>
 /// 
 /// <param name="batchGetItemRequest">Container for the necessary parameters to execute the BatchGetItem operation on AmazonDynamoDB.</param>
 /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param>
 /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback
 ///          procedure using the AsyncState property.</param>
 /// 
 /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndBatchGetItem
 ///         operation.</returns>
 public IAsyncResult BeginBatchGetItem(BatchGetItemRequest batchGetItemRequest, AsyncCallback callback, object state)
 {
     return invokeBatchGetItem(batchGetItemRequest, callback, state, false);
 }
 /// <summary>
 /// <para> The BatchGetItem operation returns the attributes for multiple items from multiple tables using their primary keys. The maximum
 /// number of item attributes that can be retrieved for a single operation is 100. Also, the number of items retrieved is constrained by a 1 MB
 /// the size limit. If the response size limit is exceeded or a partial result is returned due to an internal processing failure, Amazon
 /// DynamoDB returns an UnprocessedKeys value so you can retry the operation starting with the next item to get. Amazon DynamoDB automatically
 /// adjusts the number of items returned per page to enforce this limit. For example, even if you ask to retrieve 100 items, but each individual
 /// item is 50 KB in size, the system returns 20 items and an appropriate UnprocessedKeys value so you can get the next page of results. If
 /// necessary, your application needs its own logic to assemble the pages of results into one set. </para>
 /// </summary>
 /// 
 /// <param name="batchGetItemRequest">Container for the necessary parameters to execute the BatchGetItem service method on
 ///           AmazonDynamoDB.</param>
 /// 
 /// <returns>The response from the BatchGetItem service method, as returned by AmazonDynamoDB.</returns>
 /// 
 /// <exception cref="ProvisionedThroughputExceededException"/>
 /// <exception cref="InternalServerErrorException"/>
 /// <exception cref="ResourceNotFoundException"/>
 public BatchGetItemResponse BatchGetItem(BatchGetItemRequest batchGetItemRequest)
 {
     IRequest<BatchGetItemRequest> request = new BatchGetItemRequestMarshaller().Marshall(batchGetItemRequest);
     BatchGetItemResponse response = Invoke<BatchGetItemRequest, BatchGetItemResponse> (request, this.signer, BatchGetItemResponseUnmarshaller.GetInstance());
     return response;
 }