@Override
  public boolean isSameChunk(final Item item) {
    assertThreadInheritedTrxSet();

    if (currentAggregatedItem == null) {
      return false;
    }

    if (!currentAggregatedItem.getGroupKey().equals(item.getGroupKey())) {
      return false;
    }

    return true;
  }
  @Override
  public void process(final Item item) {
    item.setProcessed();

    Assert.assertNotNull("item shall not be null", item);
    Assert.assertNotNull("currentAggregatedItem shall be initialized", currentAggregatedItem);

    assertThreadInheritedTrxSet();

    if (errorItems.contains(item)) {
      throw new RuntimeException("Test exception for item: " + item);
    }
    currentAggregatedItem.addItem(item);
  }
  @Override
  public void completeChunk() {
    Assert.assertNotNull(
        "currentAggregatedItem shall not be null at this point", currentAggregatedItem);
    assertThreadInheritedTrxSet();

    final String groupKey = currentAggregatedItem.getGroupKey();
    if (errorOnChunkCompleteGroupKeys.contains(groupKey)) {
      throw new RuntimeException("Test exception on completeChunk for group: " + groupKey);
    }

    result.addAggregatedItem(currentAggregatedItem);
    currentAggregatedItem = null;
  }
  @Override
  public void cancelChunk() {
    Assert.assertNotNull(
        "currentAggregatedItem shall not be null at this point", currentAggregatedItem);
    assertThreadInheritedTrxSet();

    final String groupKey = currentAggregatedItem.getGroupKey();
    if (errorOnChunkCancelGroupKeys.contains(groupKey)) {
      // If we need to throw exception on cancel it means entire processing will fail
      // so there is no point to set "currentAggregatedItem" to null
      // More, we want to let it as is because it will be investigated in tests
      // currentAggregatedItem = null;

      throw new RuntimeException("Test exception on cancelChunk for group: " + groupKey);
    }

    currentAggregatedItem = null;
  }