/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode;

import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Set;

import javax.transaction.Synchronization;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;

import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.AttributesMutator;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheEvent;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.CacheListener;
import org.apache.geode.cache.CacheLoader;
import org.apache.geode.cache.CacheLoaderException;
import org.apache.geode.cache.CacheTransactionManager;
import org.apache.geode.cache.CacheWriter;
import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.CommitConflictException;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.DiskStoreFactory;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.EntryExistsException;
import org.apache.geode.cache.EntryNotFoundException;
import org.apache.geode.cache.EvictionAction;
import org.apache.geode.cache.EvictionAttributes;
import org.apache.geode.cache.FailedSynchronizationException;
import org.apache.geode.cache.LoaderHelper;
import org.apache.geode.cache.PartitionAttributes;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionEvent;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.Scope;
import org.apache.geode.cache.TimeoutException;
import org.apache.geode.cache.TransactionEvent;
import org.apache.geode.cache.TransactionException;
import org.apache.geode.cache.TransactionId;
import org.apache.geode.cache.TransactionListener;
import org.apache.geode.cache.UnsupportedOperationInTransactionException;
import org.apache.geode.cache.query.Index;
import org.apache.geode.cache.query.IndexType;
import org.apache.geode.cache.query.Query;
import org.apache.geode.cache.query.QueryException;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.cache.query.SelectResults;
import org.apache.geode.cache.query.internal.index.IndexManager;
import org.apache.geode.cache.util.CacheListenerAdapter;
import org.apache.geode.cache.util.TransactionListenerAdapter;
import org.apache.geode.cache.util.TxEventTestUtil;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.NanoTimer;
import org.apache.geode.internal.cache.AbstractRegion;
import org.apache.geode.internal.cache.CachePerfStats;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.LocalRegion;
import org.apache.geode.internal.cache.NonTXEntry;
import org.apache.geode.internal.cache.PartitionedRegion;
import org.apache.geode.internal.cache.TXManagerImpl;
import org.apache.geode.internal.cache.TXStateProxy;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.internal.util.StopWatch;

/**
 * Tests basic transaction functionality
 *
 * @since GemFire 4.0
 */
@SuppressWarnings("deprecated")
public class TXJUnitTest {

  private int cbCount;
  private TransactionEvent te;

  protected int listenerAfterCommit;
  protected int listenerAfterFailedCommit;
  protected int listenerAfterRollback;
  protected int listenerClose;
  protected CacheTransactionManager txMgr;

  protected GemFireCacheImpl cache;
  protected Region<String, String> region;

  @Rule
  public TestName testName = new TestName();

  private boolean isPR() {
    return (this.region instanceof PartitionedRegion);
  }

  protected void createCache() throws Exception {
    Properties properties = new Properties();
    properties.setProperty(MCAST_PORT, "0"); // loner

    this.cache = (GemFireCacheImpl) CacheFactory.create(DistributedSystem.connect(properties));

    createRegion();
    this.txMgr = this.cache.getCacheTransactionManager();
    this.listenerAfterCommit = 0;
    this.listenerAfterFailedCommit = 0;
    this.listenerAfterRollback = 0;
    this.listenerClose = 0;
  }

  protected void createRegion() throws Exception {
    region = createRegion(getClass().getSimpleName(), false);
  }

  protected Region createRegion(String regionName, boolean isConcurrencyChecksEnabled)
      throws Exception {
    AttributesFactory<String, String> attributesFactory = new AttributesFactory<>();
    attributesFactory
        .setDataPolicy(isConcurrencyChecksEnabled ? DataPolicy.REPLICATE : DataPolicy.NORMAL);
    attributesFactory
        .setScope(isConcurrencyChecksEnabled ? Scope.DISTRIBUTED_ACK : Scope.DISTRIBUTED_NO_ACK);
    attributesFactory.setConcurrencyChecksEnabled(isConcurrencyChecksEnabled); // test validation
                                                                               // expects this
                                                                               // behavior
    attributesFactory.setIndexMaintenanceSynchronous(true);

    return this.cache.createRegion(regionName, attributesFactory.create());
  }

  protected void closeCache() {
    if (this.cache != null) {
      if (this.txMgr != null) {
        try {
          this.txMgr.rollback();
        } catch (IllegalStateException ignore) {
        }
      }
      this.region = null;
      this.txMgr = null;
      Cache c = this.cache;
      this.cache = null;
      c.close();
    }
  }

  @Before
  public void setUpTXJUnitTest() throws Exception {
    createCache();
  }

  @After
  public void tearDownTXJUnitTest() throws Exception {
    closeCache();
  }

  @AfterClass
  public static void afterClass() {
    InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance();
    if (ids != null) {
      ids.disconnect();
    }
  }

  private void checkNoTxState() {
    assertEquals(null, this.txMgr.getTransactionId());
    assertTrue(!this.txMgr.exists());
    try {
      this.txMgr.commit();
      fail("expected IllegalStateException");
    } catch (CommitConflictException unexpected) {
      fail("did not expect " + unexpected);
    } catch (IllegalStateException expected) {
    }
    try {
      this.txMgr.rollback();
      fail("expected IllegalStateException");
    } catch (IllegalStateException expected) {
    }
  }

  @Test
  public void testSimpleOps() throws CacheException {
    final CachePerfStats stats = this.cache.getCachePerfStats();
    // See if things are ok when no transaction
    checkNoTxState();

    this.txMgr.begin();
    // now that a transaction exists make sure things behave as expected
    assertTrue(this.txMgr.getTransactionId() != null);
    assertTrue(this.txMgr.exists());
    try {
      this.txMgr.begin();
      fail("expected IllegalStateException");
    } catch (IllegalStateException expected) {
    }
    try {
      this.txMgr.commit();
    } catch (CommitConflictException unexpected) {
      fail("did not expect " + unexpected);
    }
    checkNoTxState();

    this.txMgr.begin();
    this.txMgr.rollback();
    checkNoTxState();

    this.region.put("uaKey", "val");

    {
      Region.Entry cmtre = this.region.getEntry("uaKey");
      cmtre.setUserAttribute("uaValue1");
      assertEquals("uaValue1", cmtre.getUserAttribute());

      int txRollbackChanges = stats.getTxRollbackChanges();
      int txCommitChanges = stats.getTxCommitChanges();
      int txFailureChanges = stats.getTxFailureChanges();
      this.txMgr.begin();
      Region.Entry txre = this.region.getEntry("uaKey");
      assertEquals(this.region, txre.getRegion());
      if (isPR()) {
        this.region.put("1", "one");
        try {
          txre.setUserAttribute("uaValue2");
        } catch (UnsupportedOperationException e) {
          // expected
        }
        try {
          txre.getUserAttribute();
        } catch (UnsupportedOperationException e) {
          // expected
        }
      } else {
        assertEquals("uaValue1", txre.getUserAttribute());
        txre.setUserAttribute("uaValue2");
        assertEquals("uaValue2", txre.getUserAttribute());
      }
      this.txMgr.rollback();
      try {
        txre.getValue();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txre.isDestroyed();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txre.getUserAttribute();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txre.setUserAttribute("foo");
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      assertEquals(txCommitChanges, stats.getTxCommitChanges());
      assertEquals(txFailureChanges, stats.getTxFailureChanges());

      assertEquals("uaValue1", cmtre.getUserAttribute());
    }

    {
      int txRollbackChanges = stats.getTxRollbackChanges();
      int txCommitChanges = stats.getTxCommitChanges();
      int txFailureChanges = stats.getTxFailureChanges();
      this.region.create("key1", "value1");
      this.txMgr.begin();
      this.region.invalidate("key1");
      this.txMgr.rollback();
      assertEquals(this.region.get("key1"), "value1");
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      assertEquals(txCommitChanges, stats.getTxCommitChanges());
      assertEquals(txFailureChanges, stats.getTxFailureChanges());

      txRollbackChanges = stats.getTxRollbackChanges();
      this.txMgr.begin();
      this.region.destroy("key1");
      this.txMgr.rollback();
      assertEquals(this.region.get("key1"), "value1");
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      assertEquals(txCommitChanges, stats.getTxCommitChanges());
      assertEquals(txFailureChanges, stats.getTxFailureChanges());

      txRollbackChanges = stats.getTxRollbackChanges();
      this.txMgr.begin();
      this.region.put("key1", "value2");
      this.txMgr.rollback();
      assertEquals(this.region.get("key1"), "value1");
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      assertEquals(txCommitChanges, stats.getTxCommitChanges());
      assertEquals(txFailureChanges, stats.getTxFailureChanges());
    }
  }

  @Test
  public void testWriteOps() throws CacheException {
    this.txMgr.begin();
    this.region.put("key1", "value1");
    this.region.put("key2", "value2");
    assertTrue(this.region.containsKey("key1"));
    assertTrue(this.region.containsValueForKey("key1"));
    assertEquals("key1", this.region.getEntry("key1").getKey());
    assertEquals("value1", this.region.getEntry("key1").getValue());
    assertEquals("value1", this.region.get("key1"));
    assertTrue(this.region.containsKey("key2"));
    assertTrue(this.region.containsValueForKey("key2"));
    assertEquals("key2", this.region.getEntry("key2").getKey());
    assertEquals("value2", this.region.getEntry("key2").getValue());
    assertEquals("value2", this.region.get("key2"));
    this.txMgr.rollback();
    assertTrue(!this.region.containsKey("key1"));
    assertTrue(!this.region.containsKey("key2"));

    this.txMgr.begin();
    this.region.create("key1", "value1");
    assertTrue(this.region.containsKey("key1"));
    assertTrue(this.region.containsValueForKey("key1"));
    assertEquals("key1", this.region.getEntry("key1").getKey());
    assertEquals("value1", this.region.getEntry("key1").getValue());
    assertEquals("value1", this.region.get("key1"));
    this.txMgr.rollback();
    assertTrue(!this.region.containsKey("key1"));

    this.region.create("key1", "value1");
    this.txMgr.begin();
    this.region.put("key1", "value2");
    this.txMgr.rollback();
    assertTrue(this.region.containsKey("key1"));
    assertEquals("value1", this.region.get("key1"));
    this.region.localDestroy("key1");

    this.region.create("key1", "value1");
    this.txMgr.begin();
    this.region.localDestroy("key1");
    assertTrue(!this.region.containsKey("key1"));
    assertTrue(!this.region.containsValueForKey("key1"));
    this.txMgr.rollback();
    assertTrue(this.region.containsKey("key1"));
    this.region.localDestroy("key1");

    this.region.create("key1", "value1");
    this.txMgr.begin();
    this.region.destroy("key1");
    assertTrue(!this.region.containsKey("key1"));
    assertTrue(!this.region.containsValueForKey("key1"));
    this.txMgr.rollback();
    assertTrue(this.region.containsKey("key1"));
    this.region.localDestroy("key1");

    this.region.create("key1", "value1");
    this.txMgr.begin();
    assertTrue(this.region.containsValueForKey("key1"));
    this.region.localInvalidate("key1");
    assertTrue(this.region.containsKey("key1"));
    assertTrue(!this.region.containsValueForKey("key1"));
    assertEquals(null, this.region.get("key1"));
    this.txMgr.rollback();
    assertTrue(this.region.containsValueForKey("key1"));
    this.region.localDestroy("key1");

    this.region.create("key1", "value1");
    this.txMgr.begin();
    assertTrue(this.region.containsValueForKey("key1"));
    this.region.invalidate("key1");
    assertTrue(this.region.containsKey("key1"));
    assertTrue(!this.region.containsValueForKey("key1"));
    assertEquals(null, this.region.get("key1"));
    this.txMgr.rollback();
    assertTrue(this.region.containsValueForKey("key1"));
    this.region.localDestroy("key1");

    // see if commits work
    assertTrue(!this.region.containsKey("key1"));
    assertTrue(!this.region.containsKey("key2"));
    this.txMgr.begin();
    this.region.create("key1", "value1");
    this.region.create("key2", "value2");
    this.txMgr.commit();
    assertTrue(this.region.containsKey("key1"));
    assertTrue(this.region.containsValueForKey("key1"));
    assertEquals("key1", this.region.getEntry("key1").getKey());
    assertEquals("value1", this.region.getEntry("key1").getValue());
    assertEquals("value1", this.region.get("key1"));
    assertTrue(this.region.containsKey("key2"));
    assertTrue(this.region.containsValueForKey("key2"));
    assertEquals("key2", this.region.getEntry("key2").getKey());
    assertEquals("value2", this.region.getEntry("key2").getValue());
    assertEquals("value2", this.region.get("key2"));
    this.region.localDestroy("key1");
    this.region.localDestroy("key2");
  }

  @Test
  public void testTwoRegionTxs() throws CacheException {
    final CachePerfStats stats = this.cache.getCachePerfStats();
    int txCommitChanges;
    TransactionId myTxId;

    AttributesFactory<String, String> attributesFactory = new AttributesFactory<>();
    attributesFactory.setScope(Scope.DISTRIBUTED_NO_ACK);

    Region<String, String> reg1 = this.region;
    Region<String, String> reg2 =
        this.cache.createRegion(getUniqueName(), attributesFactory.create());

    this.txMgr.setListener(new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        listenerAfterCommit = 1;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        listenerAfterFailedCommit = 1;
        te = event;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        listenerAfterRollback = 1;
        te = event;
      }

      @Override
      public void close() {
        listenerClose = 1;
      }
    });

    // see if commits work
    txCommitChanges = stats.getTxCommitChanges();
    assertTrue(!reg1.containsKey("key1"));
    assertTrue(!reg2.containsKey("key2"));
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value1");
    reg2.create("key2", "value2");
    this.txMgr.commit();
    assertTrue(reg1.containsKey("key1"));
    assertTrue(reg1.containsValueForKey("key1"));
    assertEquals("key1", reg1.getEntry("key1").getKey());
    assertEquals("value1", reg1.getEntry("key1").getValue());
    assertEquals("value1", reg1.get("key1"));
    assertTrue(reg2.containsKey("key2"));
    assertTrue(reg2.containsValueForKey("key2"));
    assertEquals("key2", reg2.getEntry("key2").getKey());
    assertEquals("value2", reg2.getEntry("key2").getValue());
    assertEquals("value2", reg2.get("key2"));
    assertEquals(txCommitChanges + 2, stats.getTxCommitChanges());
    {
      List<EntryEvent<?, ?>> creates =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(2, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1 || ev.getRegion() == reg2);
        if (ev.getRegion() == reg1) {
          assertEquals("key1", ev.getKey());
          assertEquals("value1", ev.getNewValue());
        } else {
          assertEquals("key2", ev.getKey());
          assertEquals("value2", ev.getNewValue());
        }
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");
    reg2.localDestroy("key2");

    reg2.localDestroyRegion();
  }

  @Test
  public void testTxEvent() throws CacheException {
    TransactionId myTxId;
    Region<String, String> reg1 = this.region;

    this.txMgr.setListener(new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        listenerAfterCommit = 1;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        listenerAfterFailedCommit = 1;
        te = event;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        listenerAfterRollback = 1;
        te = event;
      }

      @Override
      public void close() {
        listenerClose = 1;
      }
    });

    // make sure each operation has the correct transaction event
    // check create
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value1");
    this.txMgr.rollback();
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    {
      Cache teCache = this.te.getCache();
      assertEquals(teCache, this.cache);
      List<EntryEvent<?, ?>> creates =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value1", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }

    // check put of existing entry
    reg1.create("key1", "value0");
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    this.txMgr.rollback();
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    {
      Cache teCache = this.te.getCache();
      assertEquals(teCache, this.cache);
      List<EntryEvent<?, ?>> creates = TxEventTestUtil.getPutEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value1", ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check put of non-existent entry
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value0");
    this.txMgr.rollback();
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    {
      Cache teCache = this.te.getCache();
      assertEquals(teCache, this.cache);
      List<EntryEvent<?, ?>> creates =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value0", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }

    // check d invalidate of existing entry
    reg1.create("key1", "value0");
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.invalidate("key1");
    this.txMgr.rollback();
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    {
      Cache teCache = this.te.getCache();
      assertEquals(teCache, this.cache);
      List<EntryEvent<?, ?>> creates =
          TxEventTestUtil.getInvalidateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check l invalidate of existing entry
    reg1.create("key1", "value0");
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localInvalidate("key1");
    this.txMgr.rollback();
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    {
      Cache teCache = this.te.getCache();
      assertEquals(teCache, this.cache);
      List<EntryEvent<?, ?>> creates =
          TxEventTestUtil.getInvalidateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        if (!isPR())
          assertTrue(!ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check d destroy of existing entry
    reg1.create("key1", "value0");
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.destroy("key1");
    this.txMgr.rollback();
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    {
      Cache teCache = this.te.getCache();
      assertEquals(teCache, this.cache);
      List<EntryEvent<?, ?>> creates =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check l destroy of existing entry
    reg1.create("key1", "value0");
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localDestroy("key1");
    this.txMgr.rollback();
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    {
      Cache teCache = this.te.getCache();
      assertEquals(teCache, this.cache);
      List<EntryEvent<?, ?>> creates =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, creates.size());

      for (EntryEvent ev : creates) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        if (!isPR())
          assertTrue(!ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");
  }

  private static class CountingCallBackValidator {
    List<Object> asserts;
    final String createWriterAssert = "create writer Assert";
    final String createListenerAssert = "create listener Assert";
    final String updateWriterAssert = "update writer Assert";
    final String updateListenerAssert = "update listener Assert";
    final String invalAssert = "invalidate Assert";
    final String destroyWriterAssert = "destroy writer Assert";
    final String destroyListenerAssert = "destroy listener Assert";
    final String localDestroyWriterAssert = "local destroy writer Assert";
    final String localDestroyListenerAssert = "local destroy listener Assert";

    CountingCacheListener cl;
    CountingCacheWriter cw;

    CountingCallBackValidator(CountingCacheListener cl, CountingCacheWriter cw) {
      this.cl = cl;
      this.cw = cw;
      this.asserts = new ArrayList<>(8);
    }

    void assertCreateWriterCnt(int cnt) {
      assertCreateWriterCnt(cnt, true);
    }

    void assertCreateWriterCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(createWriterAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cw.getBeforeCreateCalls());
    }

    void assertCreateListenerCnt(int cnt) {
      assertCreateListenerCnt(cnt, true);
    }

    void assertCreateListenerCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(createListenerAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cl.getAfterCreateCalls());
    }

    void assertDestroyWriterCnt(int cnt) {
      assertDestroyWriterCnt(cnt, true);
    }

    void assertDestroyWriterCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(destroyWriterAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cw.getBeforeDestroyCalls(false));
    }

    void assertDestroyListenerCnt(int cnt) {
      assertDestroyListenerCnt(cnt, true);
    }

    void assertDestroyListenerCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(destroyListenerAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cl.getAfterDestroyCalls(false));
    }

    void assertLocalDestroyWriterCnt(int cnt) {
      assertLocalDestroyWriterCnt(cnt, true);
    }

    void assertLocalDestroyWriterCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(localDestroyWriterAssert);
        this.asserts.add(cnt);
      }
      assertEquals(0, this.cw.getBeforeDestroyCalls(true));
    }

    void assertLocalDestroyListenerCnt(int cnt) {
      assertLocalDestroyListenerCnt(cnt, true);
    }

    void assertLocalDestroyListenerCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(localDestroyListenerAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cl.getAfterDestroyCalls(true));
    }

    void assertUpdateWriterCnt(int cnt) {
      assertUpdateWriterCnt(cnt, true);
    }

    void assertUpdateWriterCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(updateWriterAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cw.getBeforeUpdateCalls());
    }

    void assertUpdateListenerCnt(int cnt) {
      assertUpdateListenerCnt(cnt, true);
    }

    void assertUpdateListenerCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(updateListenerAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cl.getAfterUpdateCalls());
    }

    void assertInvalidateCnt(int cnt) {
      assertInvalidateCnt(cnt, true);
    }

    void assertInvalidateCnt(int cnt, boolean remember) {
      if (remember) {
        this.asserts.add(invalAssert);
        this.asserts.add(cnt);
      }
      assertEquals(cnt, this.cl.getAfterInvalidateCalls());
    }

    void reAssert() {
      Iterator assertItr = this.asserts.iterator();
      String assertType;
      Integer count;
      int cnt;
      while (assertItr.hasNext()) {
        assertType = (String) assertItr.next();
        assertTrue("CountingCallBackValidator reassert, did not have an associated count",
            assertItr.hasNext());
        count = (Integer) assertItr.next();
        cnt = count;
        if (assertType.equals(createWriterAssert)) {
          this.assertCreateWriterCnt(cnt, false);
        } else if (assertType.equals(createListenerAssert)) {
          this.assertCreateListenerCnt(cnt, false);
        } else if (assertType.equals(updateWriterAssert)) {
          this.assertUpdateWriterCnt(cnt, false);
        } else if (assertType.equals(updateListenerAssert)) {
          this.assertUpdateListenerCnt(cnt, false);
        } else if (assertType.equals(invalAssert)) {
          this.assertInvalidateCnt(cnt, false);
        } else if (assertType.equals(destroyWriterAssert)) {
          this.assertDestroyWriterCnt(cnt, false);
        } else if (assertType.equals(destroyListenerAssert)) {
          this.assertDestroyListenerCnt(cnt, false);
        } else if (assertType.equals(localDestroyWriterAssert)) {
          this.assertLocalDestroyWriterCnt(cnt, false);
        } else if (assertType.equals(localDestroyListenerAssert)) {
          this.assertLocalDestroyListenerCnt(cnt, false);
        } else {
          fail("CountingCallBackValidator reassert, unknown type");
        }
      }
    }

    void reset() {
      this.cl.reset();
      this.cw.reset();
      this.asserts.clear();
    }
  }

  private interface CountingCacheListener extends CacheListener {
    int getAfterCreateCalls();

    int getAfterUpdateCalls();

    int getAfterInvalidateCalls();

    int getAfterDestroyCalls(boolean fetchLocal);

    void reset();
  }

  private interface CountingCacheWriter extends CacheWriter {
    int getBeforeCreateCalls();

    int getBeforeUpdateCalls();

    int getBeforeDestroyCalls(boolean fetchLocal);

    void reset();
  }

  @Test
  public void testTxAlgebra() throws CacheException {
    TransactionId myTxId;
    Region<String, String> reg1 = this.region;

    this.txMgr.setListener(new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        listenerAfterCommit = 1;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        listenerAfterFailedCommit = 1;
        te = event;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        listenerAfterRollback = 1;
        te = event;
      }

      @Override
      public void close() {
        listenerClose = 1;
      }
    });
    AttributesMutator<String, String> mutator = this.region.getAttributesMutator();
    CountingCacheListener cntListener = new CountingCacheListener() {
      volatile int aCreateCalls, aUpdateCalls, aInvalidateCalls, aDestroyCalls, aLocalDestroyCalls;

      @Override
      public void close() {}

      @Override
      public void reset() {
        this.aCreateCalls = this.aUpdateCalls =
            this.aInvalidateCalls = this.aDestroyCalls = this.aLocalDestroyCalls = 0;
      }

      @Override
      public void afterCreate(EntryEvent e) {
        ++this.aCreateCalls;
      }

      @Override
      public void afterUpdate(EntryEvent e) {
        ++this.aUpdateCalls;
      }

      @Override
      public void afterInvalidate(EntryEvent e) {
        ++this.aInvalidateCalls;
      }

      @Override
      public void afterDestroy(EntryEvent e) {
        if (e.getOperation().isDistributed()) {
          ++this.aDestroyCalls;
        } else {
          ++this.aLocalDestroyCalls;
        }
      }

      @Override
      public void afterRegionInvalidate(RegionEvent e) {
        fail("Unexpected afterRegionInvalidate in testTxAlgebra");
      }

      @Override
      public void afterRegionDestroy(RegionEvent e) {
        if (!e.getOperation().isClose()) {
          fail("Unexpected afterRegionDestroy in testTxAlgebra");
        }
      }

      @Override
      public void afterRegionClear(RegionEvent event) {}

      @Override
      public void afterRegionCreate(RegionEvent event) {}

      @Override
      public void afterRegionLive(RegionEvent event) {}

      @Override
      public int getAfterCreateCalls() {
        return this.aCreateCalls;
      }

      @Override
      public int getAfterUpdateCalls() {
        return this.aUpdateCalls;
      }

      @Override
      public int getAfterInvalidateCalls() {
        return this.aInvalidateCalls;
      }

      @Override
      public int getAfterDestroyCalls(boolean fetchLocal) {
        return fetchLocal ? this.aLocalDestroyCalls : this.aDestroyCalls;
      }
    };
    mutator.addCacheListener(cntListener);
    CountingCacheWriter cntWriter = new CountingCacheWriter() {
      int bCreateCalls, bUpdateCalls, bDestroyCalls, bLocalDestroyCalls;

      @Override
      public void close() {}

      @Override
      public void reset() {
        this.bCreateCalls = this.bUpdateCalls = this.bDestroyCalls = this.bLocalDestroyCalls = 0;
      }

      @Override
      public void beforeCreate(EntryEvent e) {
        ++this.bCreateCalls;
      }

      @Override
      public void beforeUpdate(EntryEvent e) {
        ++this.bUpdateCalls;
      }

      @Override
      public void beforeDestroy(EntryEvent e) {
        ++this.bDestroyCalls;
      }

      @Override
      public void beforeRegionDestroy(RegionEvent e) {
        fail("Unexpected beforeRegionDestroy in testTxAlgebra");
      }

      @Override
      public void beforeRegionClear(RegionEvent e) {
        fail("Unexpected beforeRegionClear in testTxAlgebra");
      }

      @Override
      public int getBeforeCreateCalls() {
        return this.bCreateCalls;
      }

      @Override
      public int getBeforeUpdateCalls() {
        return this.bUpdateCalls;
      }

      @Override
      public int getBeforeDestroyCalls(boolean fetchLocal) {
        return fetchLocal ? this.bLocalDestroyCalls : this.bDestroyCalls;
      }
    };
    mutator.setCacheWriter(cntWriter);

    CountingCallBackValidator callbackVal = new CountingCallBackValidator(cntListener, cntWriter);

    // make sure each op sequence has the correct affect transaction event
    // check C + C -> EX
    // check C + P -> C
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    try {
      reg1.create("key1", "value2");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ok) {
    }
    callbackVal.assertCreateWriterCnt(1, /* remember */ false);
    reg1.put("key1", "value2");
    callbackVal.assertUpdateWriterCnt(1);
    assertEquals("value2", reg1.getEntry("key1").getValue());
    // Make sure listener callbacks were not triggered before commit
    callbackVal.assertCreateListenerCnt(0, false);
    callbackVal.assertUpdateListenerCnt(0);
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value2", reg1.getEntry("key1").getValue());
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value2", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // Check C + DI -> C
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    reg1.invalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    callbackVal.assertCreateListenerCnt(0, false);
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    assertEquals(1, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // TODO: mitch implement the following
    // check LI + DI -> NOOP
    // check DI + LI -> NOOP
    // check DI + DI -> NOOP
    // check LI + LI -> NOOP

    // check C + DD -> NOOP
    callbackVal.reset();
    this.txMgr.begin();
    reg1.create("key1", "value0");
    callbackVal.assertCreateWriterCnt(1);
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    callbackVal.assertDestroyListenerCnt(0);
    this.txMgr.commit();
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, this.te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());

    // Check C + LI -> C
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // Check C + LI + C -> EX
    // Check C + LI + P -> C
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    try {
      reg1.create("key1", "ex");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ok) {
    }
    callbackVal.assertCreateWriterCnt(1, /* remember */ false);
    reg1.put("key1", "value2");
    callbackVal.assertUpdateWriterCnt(1);
    assertTrue(reg1.containsKey("key1"));
    assertEquals("value2", reg1.getEntry("key1").getValue());
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0, false);
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(reg1.containsKey("key1"));
    assertEquals("value2", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value2", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // Check C + LI + LD -> NOOP
    callbackVal.reset();
    this.txMgr.begin();
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(0, this.te.getEvents().size());

    // Check C + LI + DD -> NOOP
    callbackVal.reset();
    this.txMgr.begin();
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(0, this.te.getEvents().size());

    // check C + LD -> NOOP
    callbackVal.reset();
    this.txMgr.begin();
    reg1.create("key1", "value0");
    callbackVal.assertCreateWriterCnt(1);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(0, this.te.getEvents().size());

    // check C + LD + D -> EX
    // check C + LD + I -> EX
    // check C + LD + C -> C
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value0");
    callbackVal.assertCreateWriterCnt(1, /* remember */ false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    try {
      reg1.localDestroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertLocalDestroyWriterCnt(1, /* remember */ false);
    try {
      reg1.destroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertDestroyWriterCnt(0);
    try {
      reg1.localInvalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0);
    try {
      reg1.invalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0, /* remember */ false);
    reg1.create("key1", "value3");
    callbackVal.assertCreateWriterCnt(2);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check C + LD + P -> C
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.create("key1", "value0");
    callbackVal.assertCreateWriterCnt(1, /* remember */ false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    reg1.put("key1", "value3");
    callbackVal.assertCreateWriterCnt(2);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check put of existing entry
    // check P + C -> EX
    // check P + P -> P
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1, /* remember */ false);
    try {
      reg1.create("key1", "value2");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ok) {
    }
    callbackVal.assertUpdateWriterCnt(1, /* remember */ false);
    callbackVal.assertCreateWriterCnt(0);
    reg1.put("key1", "value3");
    callbackVal.assertUpdateWriterCnt(2);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events = TxEventTestUtil.getPutEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check P + DI -> DI
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    reg1.invalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    this.txMgr.commit();
    callbackVal.assertInvalidateCnt(1);
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.reAssert();
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getInvalidateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check P + DD -> D
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }

    // check P + LI -> LI
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(reg1.containsKey("key1"));
    assertEquals(null, reg1.getEntry("key1").getValue());
    assertTrue(!reg1.containsValueForKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getInvalidateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(!ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // Check P + LI + C -> EX
    // Check P + LI + P -> P
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1, /* remember */ false);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    try {
      reg1.create("key1", "ex");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ok) {
    }
    callbackVal.assertCreateWriterCnt(0);
    callbackVal.assertUpdateWriterCnt(1, /* remember */ false);
    reg1.put("key1", "value2");
    callbackVal.assertUpdateWriterCnt(2);
    assertTrue(reg1.containsKey("key1"));
    assertEquals("value2", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(reg1.containsKey("key1"));
    assertEquals("value2", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events = TxEventTestUtil.getPutEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value2", ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // Check P + LI + LD -> LD
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(!ev.getOperation().isDistributed());
      }
    }

    // Check P + LI + DD -> DD
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.assertDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }

    // check P + LD -> LD
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(!ev.getOperation().isDistributed());
      }
    }

    // check P + LD + D -> EX
    // check P + LD + I -> EX
    // check P + LD + C -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    try {
      reg1.localDestroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertLocalDestroyWriterCnt(1, /* remember */ false);
    try {
      reg1.destroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertDestroyWriterCnt(0);
    try {
      reg1.localInvalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0, /* remember */ false);
    try {
      reg1.invalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0);
    reg1.create("key1", "value3");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check P + LD + P -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1, /* remember */ false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    reg1.put("key1", "value3");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check DI + C -> EX
    // check DI + P -> P
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.invalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    try {
      reg1.create("key1", "value1");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ok) {
    }
    callbackVal.assertCreateWriterCnt(0);
    reg1.put("key1", "value2");
    callbackVal.assertUpdateWriterCnt(1);
    assertEquals("value2", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value2", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events = TxEventTestUtil.getPutEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value2", ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check DI + DD -> D
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.invalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }

    // check DI + LD -> LD
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.invalidate("key1");
    callbackVal.assertInvalidateCnt(0);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(!ev.getOperation().isDistributed());
      }
    }

    // check DI + LD + D -> EX
    // check DI + LD + I -> EX
    // check DI + LD + C -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.invalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    try {
      reg1.localDestroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertLocalDestroyWriterCnt(1, /* remember */ false);
    try {
      reg1.destroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertDestroyWriterCnt(0);
    try {
      reg1.localInvalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0, /* remember */ false);
    try {
      reg1.invalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0, /* remember */ false);
    reg1.create("key1", "value3");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertInvalidateCnt(0);
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check DI + LD + P -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.invalidate("key1", "value1");
    callbackVal.assertInvalidateCnt(0, false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    reg1.put("key1", "value3");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertInvalidateCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check LI + C -> EX
    // check LI + P -> P
    reg1.create("key1", "value0");
    this.txMgr.begin();
    callbackVal.reset();
    myTxId = this.txMgr.getTransactionId();
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    try {
      reg1.create("key1", "value1");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ok) {
    }
    callbackVal.assertCreateWriterCnt(0);
    reg1.put("key1", "value2");
    callbackVal.assertUpdateWriterCnt(1);
    assertEquals("value2", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.assertInvalidateCnt(0);
    callbackVal.reAssert();
    assertEquals("value2", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events = TxEventTestUtil.getPutEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value2", ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check LI + DD -> DD
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertInvalidateCnt(0);
    callbackVal.assertDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }

    // check LI + LD -> LD
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    this.txMgr.commit();
    callbackVal.assertInvalidateCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getDestroyEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals(null, ev.getNewValue());
        assertEquals("value0", ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(!ev.getOperation().isDistributed());
      }
    }

    // check LI + LD + D -> EX
    // check LI + LD + I -> EX
    // check LI + LD + C -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    try {
      reg1.localDestroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertLocalDestroyWriterCnt(1, /* remember */ false);
    try {
      reg1.destroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertDestroyWriterCnt(0);
    try {
      reg1.localInvalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0, /* remember */ false);
    try {
      reg1.invalidate("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException ok) {
    }
    callbackVal.assertInvalidateCnt(0, /* remember */ false);
    reg1.create("key1", "value3");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertInvalidateCnt(0);
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check LI + LD + P -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localInvalidate("key1", "value1");
    callbackVal.assertInvalidateCnt(0, false);
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    reg1.put("key1", "value3");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertInvalidateCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value3", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value3", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check init state LI + P + I -> I token (bug 33073)
    reg1.create("key1", "value0");
    reg1.localInvalidate("key1");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    assertEquals("value1", reg1.getEntry("key1").getValue());
    reg1.invalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    this.txMgr.commit();
    callbackVal.assertUpdateListenerCnt(0);
    callbackVal.assertInvalidateCnt(1);
    callbackVal.reAssert();
    assertNull(reg1.getEntry("key1").getValue());
    {
      // Special check to assert Invaldate token
      NonTXEntry nonTXe = (NonTXEntry) reg1.getEntry("key1");
      assertTrue(nonTXe.getRegionEntry().isInvalid());
    }
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getInvalidateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertNull(ev.getNewValue());
        assertNull(ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }

    // check init state I + P + LI -> LI token (bug 33073)
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.put("key1", "value1");
    callbackVal.assertUpdateWriterCnt(1);
    assertEquals("value1", reg1.getEntry("key1").getValue());
    reg1.localInvalidate("key1");
    callbackVal.assertInvalidateCnt(0, false);
    this.txMgr.commit();
    callbackVal.assertInvalidateCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.reAssert();
    assertNull(reg1.getEntry("key1").getValue());
    {
      // Special check to assert Local Invaldate token
      NonTXEntry nonTXe = (NonTXEntry) reg1.getEntry("key1");
      assertTrue(nonTXe.getRegionEntry().isInvalid());
    }
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getInvalidateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertNull(ev.getNewValue());
        assertNull(ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(!ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check DD + C -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value1", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value1", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value1", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check DD + P -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    reg1.put("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value1", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value1", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value1", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check LD + C -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value1", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value1", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value1", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");

    // check LD + P -> C
    reg1.create("key1", "value0");
    callbackVal.reset();
    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    reg1.localDestroy("key1");
    callbackVal.assertLocalDestroyWriterCnt(1);
    reg1.put("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    assertEquals("value1", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    callbackVal.assertLocalDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.assertUpdateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value1", reg1.getEntry("key1").getValue());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(1, this.te.getEvents().size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(this.te.getEvents());
      assertEquals(myTxId, this.te.getTransactionId());
      assertEquals(1, events.size());

      for (EntryEvent ev : events) {
        assertEquals(myTxId, ev.getTransactionId());
        assertTrue(ev.getRegion() == reg1);
        assertEquals("key1", ev.getKey());
        assertEquals("value1", ev.getNewValue());
        assertEquals(null, ev.getOldValue());
        verifyEventProps(ev);
        assertEquals(null, ev.getCallbackArgument());
        assertEquals(true, ev.isCallbackArgumentAvailable());
        assertTrue(!ev.isOriginRemote());
        assertTrue(!ev.getOperation().isExpiration());
        assertTrue(ev.getOperation().isDistributed());
      }
    }
    reg1.localDestroy("key1");
  }

  private void doNonTxInvalidateRegionOp(CachePerfStats stats) throws Exception {
    int txRollbackChanges = stats.getTxRollbackChanges();
    this.region.create("key1", "value1");
    this.region.create("key2", "value2");
    this.txMgr.begin();
    try {
      this.region.localInvalidateRegion();
      fail("Should have gotten an UnsupportedOperationInTransactionException");
    } catch (UnsupportedOperationInTransactionException ee) {
      // this is expected
    }
    this.txMgr.rollback();
    assertEquals("value1", this.region.get("key1"));
    assertEquals("value2", this.region.get("key2"));
    assertEquals(txRollbackChanges, stats.getTxRollbackChanges());

    this.region.put("key1", "value1");
    this.region.put("key2", "value2");
    this.txMgr.begin();
    try {
      this.region.invalidateRegion();
      fail("Should have gotten an UnsupportedOperationInTransactionException");
    } catch (UnsupportedOperationInTransactionException ee) {
      // this is expected
    }
    this.txMgr.rollback();
    assertEquals("value1", this.region.get("key1"));
    assertEquals("value2", this.region.get("key2"));
    assertEquals(txRollbackChanges, stats.getTxRollbackChanges());

  }

  private void doNonTxDestroyRegionOp(CachePerfStats stats) throws Exception {
    int txRollbackChanges = stats.getTxRollbackChanges();
    this.region.put("key1", "value1");
    this.region.put("key2", "value2");
    this.txMgr.begin();
    try {
      this.region.localDestroyRegion();
      fail("Should have gotten an UnsupportedOperationInTransactionException");
    } catch (UnsupportedOperationInTransactionException ee) {
      // this is expected
    }
    this.txMgr.rollback();
    assertTrue(!this.region.isDestroyed());
    assertEquals(txRollbackChanges, stats.getTxRollbackChanges());

    this.txMgr.begin();
    try {
      this.region.destroyRegion();
      fail("Should have gotten an UnsupportedOperationInTransactionException");
    } catch (UnsupportedOperationInTransactionException ee) {
      // this is expected
    }
    this.txMgr.rollback();
    assertTrue(!this.region.isDestroyed());
    assertEquals(txRollbackChanges, stats.getTxRollbackChanges());
  }

  @Test
  public void testNonTxRegionOps() throws Exception {
    final CachePerfStats stats = this.cache.getCachePerfStats();
    doNonTxInvalidateRegionOp(stats);
    doNonTxDestroyRegionOp(stats);
  }

  @Test
  public void testEntryNotFound() {
    // make sure operations that should fail with EntryNotFoundException
    // do so when done transactionally
    try {
      try {
        this.region.destroy("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }
      try {
        this.region.localDestroy("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }
      try {
        this.region.invalidate("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }
      try {
        this.region.localInvalidate("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }

      this.txMgr.begin();
      try {
        this.region.destroy("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }
      this.txMgr.rollback();
      this.txMgr.begin();
      try {
        this.region.localDestroy("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }
      this.txMgr.rollback();
      this.txMgr.begin();
      try {
        this.region.invalidate("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }
      this.txMgr.rollback();
      this.txMgr.begin();
      try {
        this.region.localInvalidate("noEntry");
        fail("expected EntryNotFoundException");
      } catch (EntryNotFoundException expected) {
      }
      this.txMgr.rollback();

      // check to see if EntryExistsException works in transactions
      this.region.create("key1", "value1");
      try {
        this.region.create("key1", "value2");
        fail("expected EntryExistsException");
      } catch (EntryExistsException expected) {
      }
      this.txMgr.begin();
      try {
        this.region.create("key1", "value2");
        fail("expected EntryExistsException");
      } catch (EntryExistsException expected) {
      }
      this.txMgr.rollback();
    } catch (CacheException ex) {
      fail("unexpected " + ex);
    }
  }

  @Test
  public void testListener() {
    assertTrue(this.txMgr.getListener() == null);
    TransactionListener oldListener = this.txMgr.setListener(new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        listenerAfterCommit = 1;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        listenerAfterFailedCommit = 1;
        te = event;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        listenerAfterRollback = 1;
        te = event;
      }

      @Override
      public void close() {
        listenerClose = 1;
      }
    });
    assertTrue(oldListener == null);
    this.txMgr.begin();
    TransactionId myTxId = this.txMgr.getTransactionId();
    assertEquals(0, this.listenerAfterRollback);
    this.txMgr.rollback();
    assertEquals(1, this.listenerAfterRollback);
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(0, this.te.getEvents().size());
    assertEquals(myTxId, this.te.getTransactionId());

    this.txMgr.begin();
    myTxId = this.txMgr.getTransactionId();
    try {
      assertEquals(0, this.listenerAfterCommit);
      this.txMgr.commit();
    } catch (CommitConflictException unexpected) {
      fail("did not expect " + unexpected);
    }
    assertEquals(1, this.listenerAfterCommit);
    assertEquals(0, TxEventTestUtil.getCreateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(this.te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(this.te.getEvents()).size());
    assertEquals(0, this.te.getEvents().size());
    assertEquals(myTxId, this.te.getTransactionId());

    assertEquals(0, this.listenerClose);
    oldListener = this.txMgr.setListener(new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        listenerAfterCommit = 2;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        listenerAfterFailedCommit = 2;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        listenerAfterRollback = 2;
        te = event;
      }

      @Override
      public void close() {
        listenerClose = 2;
      }
    });
    assertEquals(1, this.listenerClose);

    this.txMgr.begin();
    assertEquals(1, this.listenerAfterRollback);
    this.txMgr.rollback();
    assertEquals(2, this.listenerAfterRollback);
    this.txMgr.begin();
    this.txMgr.setListener(oldListener);
    assertEquals(2, this.listenerClose);
    this.txMgr.rollback();
    assertEquals(1, this.listenerAfterRollback);

    closeCache();
    assertEquals(1, this.listenerClose);
  }

  // make sure standard Cache(Listener,Writer)
  // are not called during rollback
  @Test
  public void testNoCallbacksOnRollback() throws CacheException {
    // install listeners
    AttributesMutator<String, String> mutator = this.region.getAttributesMutator();
    mutator.addCacheListener(new CacheListenerAdapter<String, String>() {
      @Override
      public void close() {
        cbCount++;
      }

      @Override
      public void afterCreate(EntryEvent event) {
        cbCount++;
      }

      @Override
      public void afterUpdate(EntryEvent event) {
        cbCount++;
      }

      @Override
      public void afterInvalidate(EntryEvent event) {
        cbCount++;
      }

      @Override
      public void afterDestroy(EntryEvent event) {
        cbCount++;
      }

      @Override
      public void afterRegionInvalidate(RegionEvent event) {
        cbCount++;
      }

      @Override
      public void afterRegionDestroy(RegionEvent event) {
        cbCount++;
      }
    });
    mutator.setCacheWriter(new CacheWriter<String, String>() {
      @Override
      public void close() {
        cbCount++;
      }

      @Override
      public void beforeUpdate(EntryEvent event) throws CacheWriterException {
        cbCount++;
      }

      @Override
      public void beforeCreate(EntryEvent event) throws CacheWriterException {
        cbCount++;
      }

      @Override
      public void beforeDestroy(EntryEvent event) throws CacheWriterException {
        cbCount++;
      }

      @Override
      public void beforeRegionDestroy(RegionEvent event) throws CacheWriterException {
        cbCount++;
      }

      @Override
      public void beforeRegionClear(RegionEvent event) throws CacheWriterException {
        cbCount++;
      }
    });

    this.txMgr.begin();
    this.region.create("key1", "value1");
    this.cbCount = 0;
    this.txMgr.rollback();
    assertEquals(0, this.cbCount);

    this.cbCount = 0;
    this.region.create("key1", "value1");
    // do a santify check to make sure callbacks are installed
    assertEquals(2, this.cbCount); // 2 -> 1writer + 1listener

    this.txMgr.begin();
    this.region.put("key1", "value2");
    this.cbCount = 0;
    this.txMgr.rollback();
    assertEquals(0, this.cbCount);
    this.region.localDestroy("key1");

    this.region.create("key1", "value1");
    this.txMgr.begin();
    this.region.localDestroy("key1");
    this.cbCount = 0;
    this.txMgr.rollback();
    assertEquals(0, this.cbCount);

    this.region.put("key1", "value1");
    this.txMgr.begin();
    this.region.destroy("key1");
    this.cbCount = 0;
    this.txMgr.rollback();
    assertEquals(0, this.cbCount);

    this.region.put("key1", "value1");
    this.txMgr.begin();
    this.region.localInvalidate("key1");
    this.cbCount = 0;
    this.txMgr.rollback();
    assertEquals(0, this.cbCount);
    this.region.localDestroy("key1");

    this.region.put("key1", "value1");
    this.txMgr.begin();
    this.region.invalidate("key1");
    this.cbCount = 0;
    this.txMgr.rollback();
    assertEquals(0, this.cbCount);

    this.region.localDestroy("key1");
  }

  /**
   * TXCallBackValidator is a container for holding state for validating Cache callbacks
   */
  private class TXCallBackValidator {
    boolean passedValidation;
    boolean suspendValidation;
    int expectedCallCount;
    Object key;
    Object oldVal;
    boolean oldValIdentCheck;
    Object newVal;
    boolean newValIdentCheck;
    TransactionId txId;
    boolean isDistributed;
    boolean isLocalLoad;
    boolean isCreate;
    boolean isUpdate;
    boolean isDestroyed;
    boolean isInvalidate;
    Object callBackArg;

    /**
     * EntryEvent, CallCount validator for callbacks (CacheWriter, CacheListener
     */
    boolean validate(EntryEvent event, int cnt) {
      if (this.isSuspendValidation()) {
        return true;
      }
      this.passedValidation = false;
      assertEquals("Expected Call Count Assertion!", this.expectedCallCount, cnt);

      assertTrue(!event.getOperation().isExpiration());
      assertTrue(!event.getOperation().isNetLoad());
      assertEquals("isLoad Assertion!", this.isLoad(), event.getOperation().isLoad());
      assertEquals("isLocalLoad Assertion!", this.isLoad(), event.getOperation().isLocalLoad());
      assertTrue(!event.getOperation().isNetSearch());
      assertTrue(!event.isOriginRemote());
      assertNotNull(event.getRegion());
      assertNotNull(event.getRegion().getCache());
      assertNotNull(event.getRegion().getCache().getCacheTransactionManager());
      assertEquals(this.getTXId(), event.getTransactionId());

      if (!isPR())
        assertEquals("IsDistributed Assertion!", this.isDistributed(),
            event.getOperation().isDistributed());
      assertEquals(this.getKey(), event.getKey());
      assertSame(this.getCallBackArg(), event.getCallbackArgument());
      if (newValIdentCheck) {
        assertSame(newVal, event.getNewValue());
      } else {
        assertEquals(newVal, event.getNewValue());
      }
      if (oldValIdentCheck) {
        assertSame(oldVal, event.getOldValue());
      } else {
        assertEquals(oldVal, event.getOldValue());
      }
      this.passedValidation = true;
      return true;
    }

    int setExpectedCount(int newVal) {
      int oldVal = this.expectedCallCount;
      this.expectedCallCount = newVal;
      return oldVal;
    }

    void setKey(Object key) {
      this.key = key;
    }

    Object getKey() {
      return this.key;
    }

    void setOldValue(Object val, boolean checkWithIdentity) {
      this.oldVal = val;
      this.oldValIdentCheck = checkWithIdentity;
    }

    Object getOldValue() {
      return this.oldVal;
    }

    void setNewValue(Object val, boolean checkWithIdentity) {
      this.newVal = val;
      this.newValIdentCheck = checkWithIdentity;
    }

    Object getNewValue() {
      return this.newVal;
    }

    TransactionId setTXId(TransactionId txId) {
      TransactionId old = this.txId;
      this.txId = txId;
      return old;
    }

    TransactionId getTXId() {
      return this.txId;
    }

    void setIsDistributed(boolean isDistributed) {
      this.isDistributed = isDistributed;
    }

    Object getCallBackArg() {
      return this.callBackArg;
    }

    void setCallBackArg(Object callBackArg) {
      this.callBackArg = callBackArg;
    }

    boolean isDistributed() {
      return this.isDistributed;
    }

    void setIsCreate(boolean isCreate) {
      this.isCreate = isCreate;
    }

    boolean isCreate() {
      return this.isCreate;
    }

    void setIsUpdate(boolean isUpdate) {
      this.isUpdate = isUpdate;
    }

    boolean isUpdate() {
      return this.isUpdate;
    }

    void setIsDestroy(boolean isDestroyed) {
      this.isDestroyed = isDestroyed;
    }

    boolean isDestroy() {
      return this.isDestroyed;
    }

    void setIsInvalidate(boolean isInvalidate) {
      this.isInvalidate = isInvalidate;
    }

    boolean isInvalidate() {
      return this.isInvalidate;
    }

    void setIsLoad(boolean isLoad) {
      this.isLocalLoad = isLoad;
    }

    boolean isLoad() {
      return this.isLocalLoad;
    }

    boolean suspendValidation(boolean toggle) {
      boolean oldVal = this.suspendValidation;
      this.suspendValidation = toggle;
      return oldVal;
    }

    boolean isSuspendValidation() {
      return this.suspendValidation;
    }

    void setPassedValidation(boolean passedValidation) {
      this.passedValidation = passedValidation;
    }

    boolean passedValidation() {
      return this.passedValidation;
    }
  }

  private interface ValidatableCacheListener extends CacheListener {
    void setValidator(TXCallBackValidator v);

    void validate();

    void validateNoEvents();

    void reset();

    void setExpectedCount(int count);

    int getCallCount();
  }

  private interface ValidatableCacheWriter extends CacheWriter {
    void setValidator(TXCallBackValidator v);

    int getCallCount();

    void localDestroyMakeup(int count);

    void validate();

    void reset();

    void validateNoEvents();
  }

  /**
   * Test to make sure CacheListener callbacks are called in place with the CacheEvents properly
   * constructed
   */
  @Test
  public void testCacheCallbacks() throws CacheException {
    final String key1 = "Key1";
    final String value1 = "value1";
    final String value2 = "value2";
    final String callBackArg = "call back arg";
    // install listeners
    AttributesMutator<String, String> mutator = this.region.getAttributesMutator();

    TXCallBackValidator cbv = new TXCallBackValidator();

    // Cache Listener
    ValidatableCacheListener vCl = new ValidatableCacheListener() {
      TXCallBackValidator v;
      int callCount;
      int prevCallCount;
      EntryEvent lastEvent;

      @Override
      public void validate() {
        this.v.validate(this.lastEvent, this.callCount);
      }

      void validate(EntryEvent event) {
        this.v.validate(event, ++this.callCount);
      }

      @Override
      public void setValidator(TXCallBackValidator v) {
        this.v = v;
      }

      @Override
      public void close() {}

      @Override
      public void afterCreate(EntryEvent event) {
        lastEvent = event;
        if (this.v.isSuspendValidation()) {
          return;
        }
        this.validate(event);
        this.v.setPassedValidation(false);
        assertTrue("IsCreate Assertion!", this.v.isCreate());
        assertTrue(event.getRegion().containsKey(this.v.getKey()));
        assertTrue(event.getRegion().containsValueForKey(this.v.getKey()));
        assertNotNull(event.getRegion().getEntry(event.getKey()).getValue());
        this.v.setPassedValidation(true);
      }

      @Override
      public void afterUpdate(EntryEvent event) {
        lastEvent = event;
        if (this.v.isSuspendValidation()) {
          return;
        }
        validate(event);
        this.v.setPassedValidation(false);
        assertTrue("IsUpdate Assertion!", this.v.isUpdate());
        assertTrue(event.getRegion().containsKey(this.v.getKey()));
        assertTrue(event.getRegion().containsValueForKey(this.v.getKey()));
        assertNotNull(event.getRegion().getEntry(event.getKey()).getValue());
        this.v.setPassedValidation(true);
      }

      @Override
      public void afterInvalidate(EntryEvent event) {
        lastEvent = event;
        if (this.v.isSuspendValidation()) {
          return;
        }
        validate(event);
        this.v.setPassedValidation(false);
        assertTrue("IsInvalidate Assertion!", this.v.isInvalidate());
        assertTrue(event.getRegion().containsKey(this.v.getKey()));
        assertTrue(!event.getRegion().containsValueForKey(this.v.getKey()));
        assertNull(event.getRegion().getEntry(event.getKey()).getValue());
        this.v.setPassedValidation(true);
      }

      @Override
      public void afterDestroy(EntryEvent event) {
        lastEvent = event;
        if (this.v.isSuspendValidation()) {
          return;
        }
        validate(event);
        this.v.setPassedValidation(false);
        assertTrue("IsDestroy Assertion!", this.v.isDestroy());
        assertTrue(!event.getRegion().containsKey(this.v.getKey()));
        assertTrue(!event.getRegion().containsValueForKey(this.v.getKey()));
        assertNull(event.getRegion().getEntry(event.getKey()));
        this.v.setPassedValidation(true);
      }

      @Override
      public void afterRegionInvalidate(RegionEvent event) {
        fail("Unexpected invocation of afterRegionInvalidate");
      }

      @Override
      public void afterRegionDestroy(RegionEvent event) {
        if (!event.getOperation().isClose()) {
          fail("Unexpected invocation of afterRegionDestroy");
        }
      }

      @Override
      public void afterRegionClear(RegionEvent event) {}

      @Override
      public void afterRegionCreate(RegionEvent event) {}

      @Override
      public void afterRegionLive(RegionEvent event) {}

      @Override
      public void reset() {
        lastEvent = null;
        prevCallCount = callCount;
      }

      @Override
      public void validateNoEvents() {
        assertNull("Did not expect listener callback", lastEvent);
        assertEquals(prevCallCount, callCount);
      }

      @Override
      public void setExpectedCount(int count) {
        callCount = count;
      }

      @Override
      public int getCallCount() {
        return callCount;
      }
    };

    vCl.setValidator(cbv);
    mutator.addCacheListener(vCl);

    // CacheWriter
    ValidatableCacheWriter vCw = new ValidatableCacheWriter() {
      TXCallBackValidator v;
      int callCount;
      int prevCallCount;
      EntryEvent lastEvent;

      @Override
      public int getCallCount() {
        return this.callCount;
      }

      @Override
      public void localDestroyMakeup(int count) {
        this.callCount += count;
      }

      @Override
      public void validate() {
        this.v.validate(this.lastEvent, this.callCount);
      }

      void validate(EntryEvent event) {
        this.v.validate(event, ++this.callCount);
      }

      @Override
      public void setValidator(TXCallBackValidator v) {
        this.v = v;
      }

      @Override
      public void close() {}

      @Override
      public void beforeCreate(EntryEvent event) {
        lastEvent = event;
        if (this.v.isSuspendValidation()) {
          return;
        }
        validate(event);
        this.v.setPassedValidation(false);
        assertTrue("IsCreate Assertion!", this.v.isCreate());
        assertTrue(!event.getRegion().containsKey(this.v.getKey()));
        assertTrue(!event.getRegion().containsValueForKey(this.v.getKey()));
        assertNull(event.getRegion().getEntry(event.getKey()));
        this.v.setPassedValidation(true);
      }

      @Override
      public void beforeUpdate(EntryEvent event) {
        lastEvent = event;
        if (this.v.isSuspendValidation()) {
          return;
        }
        validate(event);
        this.v.setPassedValidation(false);
        assertTrue("IsUpdate Assertion!", this.v.isUpdate());
        assertTrue(event.getRegion().containsKey(this.v.getKey()));
        // Can not assert the following line, as the value being update may be invalid
        // assertTrue(event.getRegion().containsValueForKey(this.v.getKey()));
        this.v.setPassedValidation(true);
      }

      @Override
      public void beforeDestroy(EntryEvent event) {
        lastEvent = event;
        if (this.v.isSuspendValidation()) {
          return;
        }
        validate(event);
        this.v.setPassedValidation(false);
        assertTrue("IsDestroy Assertion!", this.v.isDestroy());
        assertTrue(event.getRegion().containsKey(this.v.getKey()));
        this.v.setPassedValidation(true);
      }

      @Override
      public void beforeRegionDestroy(RegionEvent event) {
        fail("Unexpected invocation of beforeRegionDestroy");
      }

      @Override
      public void beforeRegionClear(RegionEvent event) {
        fail("Unexpected invocation of beforeRegionClear");
      }

      @Override
      public void reset() {
        lastEvent = null;
        prevCallCount = callCount;
      }

      @Override
      public void validateNoEvents() {
        assertNull("Did not expect a writer event", lastEvent);
        assertEquals(prevCallCount, callCount);
      }
    };
    vCw.setValidator(cbv);
    mutator.setCacheWriter(vCw);

    // Cache Loader
    mutator.setCacheLoader(new CacheLoader() {
      int count = 0;

      @Override
      public Object load(LoaderHelper helper) throws CacheLoaderException {
        return count++;
      }

      @Override
      public void close() {}
    });

    // Use this to track the number of callout method invocations
    int appCallCount = 1;

    // Create => beforeCreate/afterCreate tests
    cbv.setKey(key1);
    cbv.setCallBackArg(callBackArg);
    cbv.setNewValue(value1, false);
    cbv.setOldValue(null, true);
    cbv.setIsDistributed(true);
    cbv.setIsLoad(false);
    cbv.setIsCreate(true);
    cbv.setIsUpdate(false);
    // Test non-transactional create expecting beforeCreate/afterCreate call
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.create(key1, value1, callBackArg);
    assertTrue("Non-TX Create Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);
    cbv.suspendValidation(false);
    // Test transactional create expecting afterCreate call
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.create(key1, value1, callBackArg);
    this.txMgr.commit();
    assertTrue("TX Create Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);

    // Put => afterCreate tests
    cbv.suspendValidation(false);
    cbv.setNewValue(value2, false);
    cbv.setOldValue(null, true);
    cbv.setIsDistributed(true);
    cbv.setIsLoad(false);
    cbv.setIsCreate(true);
    cbv.setIsUpdate(false);
    // Test non-transactional put expecting afterCreate call due to no
    // previous Entry
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.put(key1, value2, callBackArg);
    assertTrue("Non-TX Put->Create Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);
    cbv.suspendValidation(false);
    // Test transactional put expecting afterCreate call due to no
    // previous Entry
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.put(key1, value2, callBackArg);
    this.txMgr.commit();
    assertTrue("TX Put->Create Validation Assertion", cbv.passedValidation());

    // Put => afterUpdate tests
    cbv.setNewValue(value1, false);
    cbv.setOldValue(value2, false);
    cbv.setIsDistributed(true);
    cbv.setIsLoad(false);
    cbv.setIsCreate(false);
    cbv.setIsUpdate(true);
    // Test non-transactional put expecting afterUpdate call due to
    // previous Entry
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.put(key1, value1, callBackArg);
    assertTrue("Non-TX Put->Update Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);
    this.region.put(key1, value2);
    cbv.suspendValidation(false);
    // Test transactional put expecting afterUpdate call due to
    // previous Entry
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.put(key1, value1, callBackArg);
    this.txMgr.commit();
    assertTrue("TX Put->Update Validation Assertion", cbv.passedValidation());

    // LocalDestroy => afterDestroy, non-distributed tests
    cbv.setNewValue(null, true);
    cbv.setOldValue(value1, false);
    cbv.setIsDistributed(false);
    cbv.setIsLoad(false);
    cbv.setIsDestroy(true);
    cbv.setIsUpdate(false);
    // Test non-transactional localDestroy, expecting afterDestroy,
    // non-distributed
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.localDestroy(key1, callBackArg);
    if (!isPR())
      vCw.localDestroyMakeup(1); // Account for cacheWriter not begin called
    assertTrue("Non-TX LocalDestroy Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.create(key1, value1);
    cbv.suspendValidation(false);
    // Test transactional localDestroy expecting afterDestroy,
    // non-distributed
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.localDestroy(key1, callBackArg);
    if (!isPR())
      vCw.localDestroyMakeup(1); // Account for cacheWriter not begin called
    this.txMgr.commit();
    assertTrue("TX LocalDestroy Validation Assertion", cbv.passedValidation());

    // Destroy => afterDestroy, distributed tests
    cbv.setNewValue(null, true);
    cbv.setOldValue(value1, false);
    cbv.setIsDistributed(true);
    cbv.setIsLoad(false);
    cbv.setIsDestroy(true);
    cbv.suspendValidation(true);
    this.region.create(key1, value1);
    cbv.suspendValidation(false);
    // Test non-transactional Destroy, expecting afterDestroy,
    // distributed
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.destroy(key1, callBackArg);
    assertTrue("Non-TX Destroy Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.create(key1, value1);
    cbv.suspendValidation(false);
    // Test transactional Destroy, expecting afterDestroy,
    // distributed
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.destroy(key1, callBackArg);
    this.txMgr.commit();
    assertTrue("TX Destroy Validation Assertion", cbv.passedValidation());

    // localInvalidate => afterInvalidate, non-distributed tests
    cbv.setNewValue(null, true);
    cbv.setOldValue(value1, false);
    cbv.setIsDistributed(false);
    cbv.setIsLoad(false);
    cbv.setIsInvalidate(true);
    cbv.setIsDestroy(false);
    cbv.suspendValidation(true);
    this.region.create(key1, value1);
    cbv.suspendValidation(false);
    // Test non-transactional localInvalidate, expecting afterInvalidate
    // non-distributed
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.localInvalidate(key1, callBackArg);
    assertTrue("Non-TX LocalInvalidate Validation Assertion", cbv.passedValidation());
    vCw.localDestroyMakeup(1); // Account for cacheWriter not begin called
    cbv.suspendValidation(true);
    this.region.put(key1, value1);
    cbv.suspendValidation(false);
    // Test transactional localInvalidate, expecting afterInvalidate
    // non-distributed
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.localInvalidate(key1, callBackArg);
    this.txMgr.commit();
    assertTrue("TX LocalInvalidate Validation Assertion", cbv.passedValidation());
    vCw.localDestroyMakeup(1); // Account for cacheWriter not begin called
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);

    // Invalidate => afterInvalidate, distributed tests
    cbv.setNewValue(null, true);
    cbv.setOldValue(value1, false);
    cbv.setIsDistributed(true);
    cbv.setIsLoad(false);
    cbv.suspendValidation(true);
    this.region.create(key1, value1);
    cbv.suspendValidation(false);
    // Test non-transactional Invalidate, expecting afterInvalidate
    // distributed
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.invalidate(key1, callBackArg);
    vCw.localDestroyMakeup(1); // Account for cacheWriter not begin called
    assertTrue("Non-TX Invalidate Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.put(key1, value1);
    cbv.suspendValidation(false);
    // Test transactional Invalidate, expecting afterInvalidate
    // distributed
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.invalidate(key1, callBackArg);
    this.txMgr.commit();
    vCw.localDestroyMakeup(1); // Account for cacheWriter not begin called
    assertTrue("TX Invalidate Validation Assertion", cbv.passedValidation());
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);
    cbv.suspendValidation(false);

    // Create load Event tests
    int loaderValCheck = 0;
    cbv.setNewValue(loaderValCheck++, false);
    cbv.setCallBackArg(null);
    cbv.setOldValue(null, false);
    cbv.setIsDistributed(true);
    cbv.setIsCreate(true);
    cbv.setIsUpdate(false);
    cbv.setIsLoad(true);
    // Test non-transactional load, expecting afterCreate distributed
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.get(key1);
    assertTrue("Non-TX Invalidate Validation Assertion", cbv.passedValidation());
    vCl.validate();
    vCw.validate();
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);
    cbv.suspendValidation(false);
    // Test transactional load, expecting afterCreate distributed
    vCl.reset();
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setNewValue(loaderValCheck++, false);
    cbv.setExpectedCount(appCallCount++);
    this.region.get(key1);
    this.txMgr.rollback();
    assertTrue("TX Invalidate Validation Assertion", cbv.passedValidation());
    vCw.validate();
    vCl.validateNoEvents();
    vCl.setExpectedCount(vCl.getCallCount() + 1);

    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setNewValue(loaderValCheck++, false);
    cbv.setExpectedCount(appCallCount++);
    this.region.get(key1);
    vCw.validate();
    vCw.reset();
    this.txMgr.commit();
    vCw.validateNoEvents();
    assertTrue("TX Invalidate Validation Assertion", cbv.passedValidation());
    vCl.validate();
    cbv.suspendValidation(true);
    this.region.localDestroy(key1);
    cbv.suspendValidation(false);

    // Update load Event tests
    cbv.suspendValidation(true);
    this.region.create(key1, null);
    cbv.suspendValidation(false);
    assertTrue(this.region.containsKey(key1));
    assertTrue(!this.region.containsValueForKey(key1));
    cbv.setNewValue(loaderValCheck++, false);
    cbv.setOldValue(null, false);
    cbv.setIsDistributed(true);
    cbv.setCallBackArg(null);
    cbv.setIsCreate(false);
    cbv.setIsUpdate(true);
    cbv.setIsLoad(true);
    // Test non-transactional load, expecting afterUpdate distributed
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    this.region.get(key1);
    assertTrue("Non-TX Invalidate Validation Assertion", cbv.passedValidation());
    vCw.validate();
    vCl.validate();
    cbv.suspendValidation(true);
    this.region.invalidate(key1);
    cbv.suspendValidation(false);
    assertTrue(this.region.containsKey(key1));
    assertTrue(!this.region.containsValueForKey(key1));
    // Test transactional load, expecting afterUpdate distributed
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    cbv.setNewValue(loaderValCheck++, false);
    this.region.get(key1);
    vCw.validate();
    vCw.reset();
    this.txMgr.commit();
    vCw.validateNoEvents();
    vCl.validate();

    cbv.suspendValidation(true);
    this.region.invalidate(key1);
    cbv.suspendValidation(false);
    vCl.reset();
    this.txMgr.begin();
    cbv.setTXId(txMgr.getTransactionId());
    cbv.setExpectedCount(appCallCount++);
    cbv.setNewValue(loaderValCheck++, false);
    this.region.get(key1);
    this.txMgr.rollback();
    assertTrue("TX Invalidate Validation Assertion", cbv.passedValidation());
    vCw.validate();
    vCl.validateNoEvents();
  }

  @Test
  public void testEntryCount() throws CacheException {
    LocalRegion reg1 = (LocalRegion) this.region;

    assertEquals(0, reg1.entryCount());
    reg1.create("key1", "value1");
    assertEquals(1, reg1.entryCount());
    reg1.create("key2", "value2");
    assertEquals(2, reg1.entryCount());
    reg1.localDestroy("key2");
    assertEquals(1, reg1.entryCount());

    reg1.create("key3", "value3");
    assertEquals(2, reg1.entryCount());

    this.txMgr.begin();
    this.region.create("key2", "value2");
    assertEquals(3, reg1.entryCount());
    reg1.localDestroy("key2");
    assertEquals(2, reg1.entryCount());

    this.region.create("key2", "value2");
    assertEquals(3, reg1.entryCount());
    reg1.destroy("key2");
    assertEquals(2, reg1.entryCount());

    reg1.localInvalidate("key1");
    assertEquals(2, reg1.entryCount());
    reg1.put("key1", "value2");
    assertEquals(2, reg1.entryCount());
    this.region.create("key2", "value2");
    assertEquals(3, reg1.entryCount());

    reg1.localDestroy("key3");
    assertEquals(2, reg1.entryCount());
    reg1.create("key3", "value3");
    assertEquals(3, reg1.entryCount());

    this.txMgr.rollback();

    assertEquals(2, reg1.entryCount());
  }

  private void checkCollectionSize(int expectedSize) {
    checkCollectionSize(expectedSize, expectedSize, expectedSize);
  }

  private void checkCollectionSize(int expectedSize, int expectedRecSize) {
    checkCollectionSize(expectedSize, expectedRecSize, expectedSize);
  }

  private void checkCollectionSize(int expectedSize, int expectedRecSize, int expectedValuesSize) {
    int size = 0;
    for (Object key : this.region.entrySet(false)) {
      size++;
    }
    assertEquals(expectedSize, size);
    assertEquals(expectedSize, this.region.keySet().size());
    assertEquals(expectedValuesSize, this.region.values().size());
    assertEquals(expectedSize, this.region.entrySet(false).size());
    assertEquals(expectedRecSize, this.region.entrySet(true).size());
  }

  @Test
  public void testCollections() throws CacheException {
    Region<String, String> reg1 = this.region;

    checkSubRegionCollection(reg1);

    {
      Collection nonTxKeys = reg1.keySet();
      Collection nonTxValues = reg1.values();
      this.txMgr.begin();
      reg1.create("key1", "value1");
      Collection txKeys = reg1.keySet();
      Collection txValues = reg1.values();
      /*
       * [sumedh] No longer fail this scenario to avoid the overhead of ThreadLocal lookup in every
       * iteration. Besides does not look to be a harmful usage in any case.
       */
      try {
        nonTxKeys.size();
        fail();
      } catch (IllegalStateException expected) {
        TransactionId txid = this.txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }
      assertEquals(1, txKeys.size());
      try {
        nonTxValues.size();
        fail();
      } catch (IllegalStateException expected) {
        TransactionId txid = this.txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }
      assertEquals(1, txValues.size());
      assertTrue(txKeys.contains("key1"));
      {
        Iterator txIt = txKeys.iterator();
        assertTrue(txIt.hasNext());
        assertTrue(txIt.hasNext());
        assertEquals("key1", txIt.next());
        assertTrue(!txIt.hasNext());
      }
      assertTrue(txValues.contains("value1"));
      {
        Iterator txIt = txValues.iterator();
        assertTrue(txIt.hasNext());
        assertTrue(txIt.hasNext());
        assertEquals("value1", txIt.next());
        assertTrue(!txIt.hasNext());
      }
      reg1.invalidate("key1");
      assertEquals(1, txKeys.size());
      assertEquals(0, txValues.size());
      assertTrue(txKeys.contains("key1"));
      assertTrue(!txValues.contains("value1"));
      reg1.create("key2", "value2");
      reg1.create("key3", "value3");
      assertEquals(3, txKeys.size());
      assertEquals(2, txValues.size());
      reg1.put("key1", "value1");
      assertEquals(3, txKeys.size());
      assertEquals(3, txValues.size());
      reg1.localInvalidate("key2");
      assertEquals(2, txValues.size());
      reg1.invalidate("key1");
      assertEquals(1, txValues.size());
      reg1.destroy("key2");
      reg1.destroy("key3");
      assertEquals(1, txKeys.size());

      reg1.destroy("key1");
      assertEquals(0, txKeys.size());
      assertTrue(!txKeys.contains("key1"));
      Iterator txIt = txKeys.iterator();
      assertTrue(!txIt.hasNext());
      this.txMgr.rollback();
      try {
        txKeys.size();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txKeys.isEmpty();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txKeys.contains("key1");
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txKeys.iterator();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      txIt.hasNext();
    }
    {
      this.txMgr.begin();
      reg1.create("key1", "value1");
      Collection txValues = reg1.values();
      assertEquals(1, txValues.size());
      assertTrue(txValues.contains("value1"));
      {
        Iterator txIt = txValues.iterator();
        assertTrue(txIt.hasNext());
        assertEquals("value1", txIt.next());
        assertTrue(!txIt.hasNext());
      }
      reg1.destroy("key1");
      assertEquals(0, txValues.size());
      assertTrue(!txValues.contains("value1"));
      assertTrue(!txValues.iterator().hasNext());
      assertTrue(!txValues.iterator().hasNext());
      this.txMgr.rollback();
    }
    {
      Collection nonTxEntries = reg1.entrySet(false);
      this.txMgr.begin();
      reg1.create("key1", "value1");
      Collection txEntries = reg1.entrySet(false);
      // non-TX collections can now be used in a transactional context
      try {
        nonTxEntries.size();
        fail();
      } catch (IllegalStateException expected) {
        TransactionId txid = this.txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }
      assertEquals(1, txEntries.size());
      assertTrue(txEntries.contains(reg1.getEntry("key1")));
      {
        Iterator txIt = txEntries.iterator();
        assertTrue(txIt.hasNext());
        assertTrue(txIt.hasNext());
        assertEquals(reg1.getEntry("key1"), txIt.next());
        assertTrue(!txIt.hasNext());
        assertTrue(!txIt.hasNext());
      }
      reg1.destroy("key1");
      assertEquals(0, txEntries.size());
      assertTrue(!txEntries.iterator().hasNext());
      this.txMgr.rollback();
    }
    {
      Collection nonTxKeys = reg1.keySet();
      Collection nonTxValues = reg1.values();

      assertEquals(0, nonTxKeys.size());
      assertEquals(0, nonTxValues.size());
      reg1.create("key1", "value1");
      assertEquals(1, nonTxKeys.size());
      assertEquals(1, nonTxValues.size());
      reg1.invalidate("key1");
      assertEquals(1, nonTxKeys.size());
      assertEquals(0, nonTxValues.size());

      this.txMgr.begin();
      Collection txKeys = reg1.keySet();
      Collection txValues = reg1.values();
      assertEquals(1, txKeys.size());
      assertEquals(0, txValues.size());
      reg1.put("key1", "txValue1");
      assertEquals(1, txKeys.size());
      assertEquals(1, txValues.size());
      assertTrue(txValues.iterator().hasNext());
      assertEquals("txValue1", txValues.iterator().next());
      // non-TX collections can now be used in a transactional context
      try {
        nonTxValues.iterator().hasNext();
      } catch (IllegalStateException expected) {
        TransactionId txid = this.txMgr.getTransactionId();
        assertEquals(
            String.format(
                "The Region collection is not transactional but is being used in a transaction %s.",
                txid),
            expected.getMessage());
      }

      reg1.localInvalidate("key1");
      assertEquals(0, txValues.size());
      assertTrue(!txValues.iterator().hasNext());
      this.txMgr.rollback();
    }
  }

  protected void checkSubRegionCollection(Region<String, String> reg1) {
    AttributesFactory<String, String> attributesFactory = new AttributesFactory<>();
    attributesFactory.setScope(Scope.DISTRIBUTED_NO_ACK);

    Region<String, String> sub1 =
        this.region.createSubregion("collectionSub1", attributesFactory.create());

    attributesFactory = new AttributesFactory<>();

    Region<String, String> sub2 =
        this.region.createSubregion("collectionSub2", attributesFactory.create());

    attributesFactory = new AttributesFactory<>();
    attributesFactory.setScope(Scope.LOCAL);

    Region<String, String> sub2_1 =
        sub2.createSubregion("collectionSub2_1", attributesFactory.create());

    checkCollectionSize(0);
    try {
      this.region.keySet().iterator().next();
      fail();
    } catch (NoSuchElementException expected) {
      assertNull(expected.getMessage());
    }
    try {
      this.region.values().iterator().next();
      fail();
    } catch (NoSuchElementException expected) {
      assertNull(expected.getMessage());
    }
    try {
      this.region.entrySet().iterator().next();
      fail();
    } catch (NoSuchElementException expected) {
      assertNull(expected.getMessage());
    }
    reg1.create("key1", "value1");
    checkCollectionSize(1);
    {
      Iterator it = this.region.keySet().iterator();
      it.next();
      try {
        it.next();
        fail();
      } catch (NoSuchElementException expected) {
        assertNull(expected.getMessage());
      }
    }
    {
      Iterator it = this.region.values().iterator();
      it.next();
      try {
        it.next();
        fail();
      } catch (NoSuchElementException expected) {
        assertNull(expected.getMessage());
      }
    }
    {
      Iterator it = this.region.entrySet().iterator();
      it.next();
      try {
        it.next();
        fail();
      } catch (NoSuchElementException expected) {
        assertNull(expected.getMessage());
      }
    }

    reg1.create("key2", "value2");
    checkCollectionSize(2);
    reg1.localInvalidate("key2");
    checkCollectionSize(2, 2, 1);
    reg1.localInvalidate("key1");
    checkCollectionSize(2, 2, 0);
    reg1.localDestroy("key2");
    checkCollectionSize(1, 1, 0);
    reg1.localDestroy("key1");
    checkCollectionSize(0);


    // Non-TX recursive checks
    sub2_1.create("key6", "value6");
    checkCollectionSize(0, 1);
    assertEquals(0, sub2.entrySet(false).size());
    assertEquals(1, sub2.entrySet(true).size());
    assertEquals(1, sub2_1.entrySet(true).size());
    sub2.create("key5", "value5");
    checkCollectionSize(0, 2);
    assertEquals(1, sub2.entrySet(false).size());
    assertEquals(2, sub2.entrySet(true).size());
    sub1.create("key4", "value4");
    checkCollectionSize(0, 3);
    assertEquals(1, sub1.entrySet(false).size());
    assertEquals(1, sub1.entrySet(true).size());
    reg1.put("key1", "value1");
    checkCollectionSize(1, 4);
    sub2.localDestroy("key5");
    checkCollectionSize(1, 3);
    assertEquals(0, sub2.entrySet(false).size());
    assertEquals(1, sub2.entrySet(true).size());
    assertEquals(1, sub2_1.entrySet(false).size());
    assertEquals(1, sub2_1.entrySet(true).size());
    sub2_1.localDestroy("key6");
    checkCollectionSize(1, 2);
    assertEquals(0, sub2.entrySet(false).size());
    assertEquals(0, sub2.entrySet(true).size());
    assertEquals(0, sub2_1.entrySet(false).size());
    sub1.localDestroy("key4");
    checkCollectionSize(1, 1);
    assertEquals(0, sub1.entrySet(false).size());
    assertEquals(0, sub1.entrySet(true).size());

    reg1.create("key3", "value3");
    sub1.create("key4", "value4");
    sub2.create("key5", "value5");
    sub2_1.create("key6", "value6");
    checkCollectionSize(2, 5);

    this.txMgr.begin();
    this.region.create("key2", "value2");
    checkCollectionSize(3, 6);
    reg1.localDestroy("key2");
    checkCollectionSize(2, 5);
    this.region.create("key2", "value2");
    checkCollectionSize(3, 6);
    reg1.destroy("key2");
    checkCollectionSize(2, 5);
    reg1.put("key1", "value2");
    checkCollectionSize(2, 5);
    this.region.create("key2", "value2");
    checkCollectionSize(3, 6);
    reg1.localDestroy("key3");
    checkCollectionSize(2, 5);
    reg1.create("key3", "value3");
    checkCollectionSize(3, 6);

    // TX recursive checks
    sub2.destroy("key5");
    checkCollectionSize(3, 5);
    assertEquals(1, sub1.entrySet(false).size());
    assertEquals(1, sub1.entrySet(true).size());
    assertEquals(0, sub2.entrySet(false).size());
    assertEquals(1, sub2.entrySet(true).size());
    assertEquals(1, sub2_1.entrySet(false).size());
    assertEquals(1, sub2_1.entrySet(true).size());
    sub2_1.destroy("key6");
    checkCollectionSize(3, 4);
    assertEquals(1, sub1.entrySet(false).size());
    assertEquals(1, sub1.entrySet(true).size());
    assertEquals(0, sub2.entrySet(false).size());
    assertEquals(0, sub2.entrySet(true).size());
    assertEquals(0, sub2_1.entrySet(false).size());
    assertEquals(0, sub2_1.entrySet(true).size());
    sub1.localDestroy("key4");
    checkCollectionSize(3, 3);
    assertEquals(0, sub1.entrySet(false).size());
    assertEquals(0, sub1.entrySet(true).size());
    assertEquals(0, sub2.entrySet(false).size());
    assertEquals(0, sub2.entrySet(true).size());
    assertEquals(0, sub2_1.entrySet(false).size());
    assertEquals(0, sub2_1.entrySet(true).size());
    sub2.put("key5", "value5");
    checkCollectionSize(3, 4);
    assertEquals(0, sub1.entrySet(false).size());
    assertEquals(0, sub1.entrySet(true).size());
    assertEquals(1, sub2.entrySet(false).size());
    assertEquals(1, sub2.entrySet(true).size());
    assertEquals(0, sub2_1.entrySet(false).size());
    assertEquals(0, sub2_1.entrySet(true).size());
    sub2_1.put("key6", "value6");
    checkCollectionSize(3, 5);
    assertEquals(0, sub1.entrySet(false).size());
    assertEquals(0, sub1.entrySet(true).size());
    assertEquals(1, sub2.entrySet(false).size());
    assertEquals(2, sub2.entrySet(true).size());
    assertEquals(1, sub2_1.entrySet(false).size());
    assertEquals(1, sub2_1.entrySet(true).size());
    sub1.put("key4", "value4");
    checkCollectionSize(3, 6);
    assertEquals(1, sub1.entrySet(false).size());
    assertEquals(1, sub1.entrySet(true).size());
    assertEquals(1, sub2.entrySet(false).size());
    assertEquals(2, sub2.entrySet(true).size());
    assertEquals(1, sub2_1.entrySet(false).size());
    assertEquals(1, sub2_1.entrySet(true).size());
    sub2_1.put("key7", "value7");
    checkCollectionSize(3, 7);
    assertEquals(1, sub1.entrySet(false).size());
    assertEquals(1, sub1.entrySet(true).size());
    assertEquals(1, sub2.entrySet(false).size());
    assertEquals(3, sub2.entrySet(true).size());
    assertEquals(2, sub2_1.entrySet(false).size());
    assertEquals(2, sub2_1.entrySet(true).size());

    this.txMgr.rollback();
    checkCollectionSize(2, 5);

    // disabling these in a TX because they throw and don't work now!
    // this.txMgr.begin();
    sub2.destroyRegion();
    checkCollectionSize(2, 3);
    sub1.destroyRegion();
    checkCollectionSize(2);

    reg1.localDestroy("key1");
    reg1.localDestroy("key3");
    checkCollectionSize(0);
  }

  @Test
  public void testLoader() throws CacheException {
    AttributesMutator<String, String> mutator = this.region.getAttributesMutator();
    mutator.setCacheLoader(new CacheLoader<String, String>() {
      int count = 0;

      @Override
      public String load(LoaderHelper helper) throws CacheLoaderException {
        count++;
        return "LV " + count;
      }

      @Override
      public void close() {}
    });
    LocalRegion reg1 = (LocalRegion) this.region;
    if (isPR())
      ((PartitionedRegion) reg1).setHaveCacheLoader();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 1", reg1.get("key1"));
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 1", reg1.getEntry("key1").getValue());
    reg1.localDestroy("key1");

    // TX load: only TX
    this.txMgr.begin();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 2", reg1.get("key1"));
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 2", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();
    assertTrue(!reg1.containsKey("key1"));
    // assertIndexDetailsEquals("LV 2", reg1.getEntry("key1").getValue());
    // reg1.localDestroy("key1");
    // TX load: commit check
    this.txMgr.begin();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 3", reg1.get("key1"));
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 3", reg1.getEntry("key1").getValue());
    this.txMgr.commit();
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 3", reg1.getEntry("key1").getValue());
    reg1.localDestroy("key1");
    // TX load YES conflict: no-initial state, tx create, committed load
    {
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TXStateProxy tx;
      this.txMgr.begin();
      reg1.create("key1", "txValue");
      assertEquals("txValue", reg1.getEntry("key1").getValue());
      tx = txMgrImpl.pauseTransaction();
      assertTrue(!reg1.containsKey("key1"));
      assertEquals("LV 4", reg1.get("key1"));
      assertTrue(reg1.containsKey("key1"));
      txMgrImpl.unpauseTransaction(tx);
      assertEquals("txValue", reg1.getEntry("key1").getValue());
      assertEquals("txValue", reg1.get("key1"));
      try {
        this.txMgr.commit();
        fail("Should have thrown a commit conflict");
      } catch (CommitConflictException cce) {
        // this is what we want
      }
      assertEquals("LV 4", reg1.getEntry("key1").getValue());
      assertEquals("LV 4", reg1.get("key1"));
      reg1.localDestroy("key1");
    }
    // TX load no conflict: load initial state, tx update
    assertEquals("LV 5", reg1.get("key1"));
    this.txMgr.begin();
    reg1.put("key1", "txValue");
    assertEquals("txValue", reg1.get("key1"));
    assertEquals("txValue", reg1.getEntry("key1").getValue());
    this.txMgr.commit(); // no conflict! Make sure committed value overrode initial state
    assertEquals("txValue", reg1.getEntry("key1").getValue());
    assertEquals("txValue", reg1.get("key1"));
    reg1.localDestroy("key1");
    // TX load no conflict: load initial state, tx load
    assertEquals("LV 6", reg1.get("key1"));
    this.txMgr.begin();
    reg1.localInvalidate("key1");
    assertEquals("LV 7", reg1.get("key1"));
    assertEquals("LV 7", reg1.getEntry("key1").getValue());
    this.txMgr.commit(); // no conflict! Make sure committed value overrode initial state
    assertEquals("LV 7", reg1.getEntry("key1").getValue());
    assertEquals("LV 7", reg1.get("key1"));
    reg1.localDestroy("key1");

    // TX load no conflict: no initial state, tx load, committed create
    {
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TXStateProxy tx;
      this.txMgr.begin();
      assertEquals("LV 8", reg1.get("key1"));
      assertEquals("LV 8", reg1.getEntry("key1").getValue());
      tx = txMgrImpl.pauseTransaction();
      assertTrue(!reg1.containsKey("key1"));
      reg1.create("key1", "txValue");
      assertTrue(reg1.containsKey("key1"));
      assertEquals("txValue", reg1.get("key1"));
      txMgrImpl.unpauseTransaction(tx);
      assertEquals("LV 8", reg1.getEntry("key1").getValue());
      try {
        this.txMgr.commit(); // should conflict
        fail("Should have thrown cce");
      } catch (CommitConflictException cce) {
        // this is what we want
      }
      assertEquals("txValue", reg1.getEntry("key1").getValue());
      assertEquals("txValue", reg1.get("key1"));
      reg1.localDestroy("key1");
    }
    // TX load conflict: no-inital state, tx load->update, committed update
    {
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TransactionId txId = null;
      this.txMgr.begin();
      reg1.create("key1", "txValue");
      txId = txMgrImpl.suspend();
      assertTrue(!reg1.containsKey("key1"));
      // new transaction, load(create) + put
      this.txMgr.begin();
      assertEquals("LV 9", reg1.get("key1"));
      assertEquals("LV 9", reg1.getEntry("key1").getValue());
      reg1.put("key1", "txValue2");
      assertEquals("txValue2", reg1.get("key1"));
      assertEquals("txValue2", reg1.getEntry("key1").getValue());
      this.txMgr.commit();
      assertTrue(reg1.containsKey("key1"));
      assertEquals("txValue2", reg1.get("key1"));
      assertEquals("txValue2", reg1.getEntry("key1").getValue());
      txMgrImpl.resume(txId);
      assertEquals("txValue", reg1.getEntry("key1").getValue());
      assertEquals("txValue", reg1.get("key1"));
      try {
        this.txMgr.commit();
        fail("expected CommitConflictException!");
      } catch (CommitConflictException expected) {
      }
      assertTrue(reg1.containsKey("key1"));
      assertEquals("txValue2", reg1.get("key1"));
      assertEquals("txValue2", reg1.getEntry("key1").getValue());
      reg1.localDestroy("key1");
    }

    // TX load repeat: no-initial state, tx load->get
    this.txMgr.begin();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 10", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 10", reg1.getEntry("key1").getValue());
    assertEquals("LV 10", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 10", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: no-initial state, tx load->localDestory->load
    this.txMgr.begin();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 11", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 11", reg1.getEntry("key1").getValue());
    reg1.localDestroy("key1");
    assertEquals("LV 12", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 12", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: no-initial state: tx load->destroy->load
    this.txMgr.begin();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 13", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 13", reg1.getEntry("key1").getValue());
    reg1.destroy("key1");
    assertEquals("LV 14", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 14", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: no-initial state, tx load->localInvalidate->load
    this.txMgr.begin();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 15", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 15", reg1.getEntry("key1").getValue());
    reg1.localInvalidate("key1");
    assertEquals("LV 16", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 16", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: no-initial, tx load->invalidate->load
    this.txMgr.begin();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals("LV 17", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 17", reg1.getEntry("key1").getValue());
    reg1.invalidate("key1");
    assertEquals("LV 18", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 18", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: invalid entry initial state, tx load->get
    reg1.create("key1", null);
    this.txMgr.begin();
    assertTrue(reg1.containsKey("key1"));
    assertNull(reg1.getEntry("key1").getValue());
    assertEquals("LV 19", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 19", reg1.getEntry("key1").getValue());
    assertEquals("LV 19", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 19", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: invalid entry initial state, tx load->localDestory->load
    this.txMgr.begin();
    assertTrue(reg1.containsKey("key1"));
    assertNull(reg1.getEntry("key1").getValue());
    assertEquals("LV 20", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 20", reg1.getEntry("key1").getValue());
    reg1.localDestroy("key1");
    assertEquals("LV 21", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 21", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: invalid entry initial state: tx load->destroy->load
    this.txMgr.begin();
    assertTrue(reg1.containsKey("key1"));
    assertNull(reg1.getEntry("key1").getValue());
    assertEquals("LV 22", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 22", reg1.getEntry("key1").getValue());
    reg1.destroy("key1");
    assertEquals("LV 23", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 23", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: invalid entry initial state, tx load->localInvalidate->load
    this.txMgr.begin();
    assertTrue(reg1.containsKey("key1"));
    assertNull(reg1.getEntry("key1").getValue());
    assertEquals("LV 24", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 24", reg1.getEntry("key1").getValue());
    reg1.localInvalidate("key1");
    assertEquals("LV 25", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 25", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // TX load repeat: invalid entry initial state, tx load->invalidate->load
    this.txMgr.begin();
    assertTrue(reg1.containsKey("key1"));
    assertNull(reg1.getEntry("key1").getValue());
    assertEquals("LV 26", reg1.get("key1")); // first invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 26", reg1.getEntry("key1").getValue());
    reg1.invalidate("key1");
    assertEquals("LV 27", reg1.get("key1")); // second invocation
    assertTrue(reg1.containsKey("key1"));
    assertEquals("LV 27", reg1.getEntry("key1").getValue());
    this.txMgr.rollback();

    // Make sure a load does not conflict with the region being destroyed
    this.txMgr.begin();
    assertEquals("LV 28", reg1.get("key2"));

    this.txMgr.commit();
    reg1.localDestroyRegion(); // non-tx region op
    // reg1 is now destroyed
  }

  @Test
  public void testStats() throws CacheException {
    final int SLEEP_MS = 250;
    // final int OP_TIME = 0; // ns // changed form 10 to 0 because on fater platforms
    // and low resolution clocks this test will fail.
    final CachePerfStats stats = this.cache.getCachePerfStats();

    class statsValidator {
      private long txSuccessLifeTime;
      private long txFailedLifeTime;
      private long txRollbackLifeTime;
      private int txCommits;
      private int txFailures;
      private int txRollbacks;
      private long txCommitTime;
      private long txFailureTime;
      private long txRollbackTime;
      private int txCommitChanges;
      private int txFailureChanges;
      private int txRollbackChanges;

      private CachePerfStats stats;

      private statsValidator(CachePerfStats stats) {
        this.stats = stats;
      }

      private void reset() {
        this.txSuccessLifeTime = this.stats.getTxSuccessLifeTime();
        this.txFailedLifeTime = this.stats.getTxFailedLifeTime();
        this.txRollbackLifeTime = this.stats.getTxRollbackLifeTime();
        this.txCommits = this.stats.getTxCommits();
        this.txFailures = this.stats.getTxFailures();
        this.txRollbacks = this.stats.getTxRollbacks();
        this.txCommitTime = this.stats.getTxCommitTime();
        this.txFailureTime = this.stats.getTxFailureTime();
        this.txRollbackTime = this.stats.getTxRollbackTime();
        this.txCommitChanges = this.stats.getTxCommitChanges();
        this.txFailureChanges = this.stats.getTxFailureChanges();
        this.txRollbackChanges = this.stats.getTxRollbackChanges();
      }

      private void setTxSuccessLifeTime(long txSuccessLifeTime) {
        this.txSuccessLifeTime = txSuccessLifeTime;
      }

      private void setTxFailedLifeTime(long txFailedLifeTime) {
        this.txFailedLifeTime = txFailedLifeTime;
      }

      private void setTxRollbackLifeTime(long txRollbackLifeTime) {
        this.txRollbackLifeTime = txRollbackLifeTime;
      }

      private void setTxCommits(int txCommits) {
        this.txCommits = txCommits;
      }

      private void setTxFailures(int txFailures) {
        this.txFailures = txFailures;
      }

      private void setTxRollbacks(int txRollbacks) {
        this.txRollbacks = txRollbacks;
      }

      private void setTxCommitTime(long txCommitTime) {
        this.txCommitTime = txCommitTime;
      }

      private void setTxFailureTime(long txFailureTime) {
        this.txFailureTime = txFailureTime;
      }

      private void setTxRollbackTime(long txRollbackTime) {
        this.txRollbackTime = txRollbackTime;
      }

      private void setTxCommitChanges(int txCommitChanges) {
        this.txCommitChanges = txCommitChanges;
      }

      private void setTxFailureChanges(int txFailureChanges) {
        this.txFailureChanges = txFailureChanges;
      }

      private void setTxRollbackChanges(int txRollbackChanges) {
        this.txRollbackChanges = txRollbackChanges;
      }

      private void assertValid() {
        assertEquals(this.txRollbacks, this.stats.getTxRollbacks());
        assertEquals(this.txRollbackChanges, this.stats.getTxRollbackChanges());
        if (Boolean
            .getBoolean(DistributionConfig.GEMFIRE_PREFIX + "cache.enable-time-statistics")) {
          assertTrue(this.txRollbackTime <= this.stats.getTxRollbackTime());
          // assertTrue(this.txRollbackLifeTime+((SLEEP_MS-10)*1000000) <=
          // this.stats.getTxRollbackLifeTime());
          assertTrue(
              "RollbackLifeTime " + this.txRollbackLifeTime + " is not <= "
                  + this.stats.getTxRollbackLifeTime(),
              this.txRollbackLifeTime <= this.stats.getTxRollbackLifeTime());
          assertTrue(this.txCommitTime <= this.stats.getTxCommitTime());
          assertTrue(this.txSuccessLifeTime <= this.stats.getTxSuccessLifeTime());
          assertTrue(this.txFailureTime <= this.stats.getTxFailureTime());
          assertTrue(
              "FailedLifeTime " + this.txFailedLifeTime + " is not <= "
                  + this.stats.getTxFailedLifeTime(),
              this.txFailedLifeTime <= this.stats.getTxFailedLifeTime());
        }

        assertEquals(this.txCommits, this.stats.getTxCommits());
        assertEquals(this.txCommitChanges, this.stats.getTxCommitChanges());

        assertEquals(this.txFailures, this.stats.getTxFailures());
        assertEquals(this.txFailureChanges, this.stats.getTxFailureChanges());
      }
    }

    statsValidator statsVal = new statsValidator(stats);
    // Zero and non-zero rollback stats test
    int i;
    long testRollbackLifeTime = 0, testTotalTx = 0;
    for (i = 0; i < 2; ++i) {
      statsVal.reset();
      statsVal.setTxRollbacks(stats.getTxRollbacks() + 1);
      statsVal.setTxRollbackLifeTime(stats.getTxRollbackLifeTime() + ((SLEEP_MS - 20) * 1000000));
      final long beforeBegin = NanoTimer.getTime();
      this.txMgr.begin();
      final long afterBegin = NanoTimer.getTime();
      pause(SLEEP_MS);
      if (i > 0) {
        statsVal.setTxRollbackChanges(stats.getTxRollbackChanges() + 2);
        this.region.put("stats1", "stats rollback1");
        this.region.put("stats2", "stats rollback2");
      }
      statsVal.setTxRollbackTime(stats.getTxRollbackTime());
      final long beforeRollback = NanoTimer.getTime();
      this.txMgr.rollback();
      final long afterRollback = NanoTimer.getTime();
      final long statsRollbackLifeTime = stats.getTxRollbackLifeTime();
      testRollbackLifeTime += beforeRollback - afterBegin;
      // bruce - time based stats are disabled by default
      String p = (String) cache.getDistributedSystem().getProperties()
          .get(DistributionConfig.GEMFIRE_PREFIX + "enable-time-statistics");
      if (p != null && Boolean.getBoolean(p)) {
        assertTrue("Local RollbackLifeTime assertion:  " + testRollbackLifeTime + " is not <= "
            + statsRollbackLifeTime, testRollbackLifeTime <= statsRollbackLifeTime);
      }
      testTotalTx += afterRollback - beforeBegin;
      final long totalTXMinusRollback = testTotalTx - stats.getTxRollbackTime();
      if (Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "cache.enable-time-statistics")) {
        assertTrue("Total Tx Minus Rollback assertion:  " + totalTXMinusRollback + " is not >= "
            + statsRollbackLifeTime, totalTXMinusRollback >= statsRollbackLifeTime);
      }
      statsVal.assertValid();
    }

    // Zero and non-zero commit stats test
    for (i = 0; i < 2; ++i) {
      statsVal.reset();
      statsVal.setTxCommits(stats.getTxCommits() + 1);
      statsVal.setTxSuccessLifeTime(stats.getTxSuccessLifeTime() + ((SLEEP_MS - 10) * 1000000));
      this.txMgr.begin();
      pause(SLEEP_MS);
      if (i > 0) {
        statsVal.setTxCommitChanges(stats.getTxCommitChanges() + 2);
        this.region.put("stats1", "commit1");
        this.region.put("stats2", "commit2");
      }
      try {
        statsVal.setTxCommitTime(stats.getTxCommitTime());
        this.txMgr.commit();
      } catch (CommitConflictException ex) {
        fail("unexpected " + ex);
      }
      statsVal.assertValid();
    }

    // Non-zero failed commit stats
    TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
    statsVal.reset();
    statsVal.setTxFailures(stats.getTxFailures() + 1);
    statsVal.setTxFailureChanges(stats.getTxFailureChanges() + 2);
    statsVal.setTxFailedLifeTime(stats.getTxFailedLifeTime() + ((SLEEP_MS - 20) * 1000000));
    this.region.put("stats3", "stats fail3");
    this.txMgr.begin();
    this.region.put("stats1", "stats fail1");
    this.region.put("stats2", "stats fail2");
    try {
      this.region.create("stats3", "try stats3");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ok) {
    }
    // begin other tx simulation
    TXStateProxy tx = txMgrImpl.pauseTransaction();
    this.region.put("stats1", "stats success1");
    this.region.put("stats2", "stats success2");
    txMgrImpl.unpauseTransaction(tx);
    // end other tx simulation
    pause(SLEEP_MS);
    try {
      statsVal.setTxFailureTime(stats.getTxFailureTime());
      this.txMgr.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
      // expected failure
    }
    statsVal.assertValid();
  }

  @Test
  public void testCacheStats() throws CacheException {
    CachePerfStats cacheStats = this.cache.getCachePerfStats();
    // quick sanity check to make sure perf stats work non-tx
    long creates;
    long destroys;
    long puts;
    long invalidates;

    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.region.create("key1", "value1");
    assertEquals(creates + 1, cacheStats.getCreates());
    assertEquals(destroys, cacheStats.getDestroys());
    assertEquals(puts + 1, cacheStats.getPuts());
    assertEquals(invalidates, cacheStats.getInvalidates());

    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.region.put("key1", "value2");
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(destroys, cacheStats.getDestroys());
    assertEquals(puts + 1, cacheStats.getPuts());
    assertEquals(invalidates, cacheStats.getInvalidates());

    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.region.invalidate("key1");
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(destroys, cacheStats.getDestroys());
    assertEquals(puts, cacheStats.getPuts());
    assertEquals(invalidates + 1, cacheStats.getInvalidates());

    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.region.destroy("key1");
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(destroys + 1, cacheStats.getDestroys());
    assertEquals(puts, cacheStats.getPuts());
    assertEquals(invalidates, cacheStats.getInvalidates());

    // now make sure they do not change from tx ops and from rollbacks
    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.txMgr.begin();
    this.region.create("key1", "value1");
    this.region.put("key1", "value2");
    this.region.invalidate("key1");
    this.region.put("key1", "value3");
    this.region.localInvalidate("key1");
    this.region.put("key1", "value4");
    this.region.localDestroy("key1");
    this.region.put("key1", "value5");
    this.region.destroy("key1");
    this.txMgr.rollback();
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(destroys, cacheStats.getDestroys());
    assertEquals(puts, cacheStats.getPuts());
    assertEquals(invalidates, cacheStats.getInvalidates());

    // now make sure they do change when a commit is done
    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.txMgr.begin();
    this.region.create("key1", "value1");
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(puts, cacheStats.getPuts());
    this.txMgr.commit();
    assertEquals(creates + 1, cacheStats.getCreates());
    assertEquals(destroys, cacheStats.getDestroys());
    assertEquals(puts + 1, cacheStats.getPuts());
    assertEquals(invalidates, cacheStats.getInvalidates());

    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.txMgr.begin();
    this.region.put("key1", "value1");
    assertEquals(puts, cacheStats.getPuts());
    this.txMgr.commit();
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(destroys, cacheStats.getDestroys());
    assertEquals(puts + 1, cacheStats.getPuts());
    assertEquals(invalidates, cacheStats.getInvalidates());

    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.txMgr.begin();
    this.region.localInvalidate("key1");
    assertEquals(invalidates, cacheStats.getInvalidates());
    this.txMgr.commit();
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(destroys, cacheStats.getDestroys());
    assertEquals(puts, cacheStats.getPuts());
    assertEquals(invalidates + 1, cacheStats.getInvalidates());

    creates = cacheStats.getCreates();
    destroys = cacheStats.getDestroys();
    puts = cacheStats.getPuts();
    invalidates = cacheStats.getInvalidates();
    this.txMgr.begin();
    this.region.localDestroy("key1");
    assertEquals(destroys, cacheStats.getDestroys());
    this.txMgr.commit();
    assertEquals(creates, cacheStats.getCreates());
    assertEquals(destroys + 1, cacheStats.getDestroys());
    assertEquals(puts, cacheStats.getPuts());
    assertEquals(invalidates, cacheStats.getInvalidates());
  }

  private void pause(int msWait) {
    try {
      Thread.sleep(msWait);
    } catch (InterruptedException ignore) {
      fail("interrupted");
    }
  }

  @Test
  public void testPauseUnpause() {
    TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
    assertTrue(!this.txMgr.exists());
    assertEquals(null, txMgrImpl.pauseTransaction());
    TXStateProxy txProxy = null;
    txMgrImpl.unpauseTransaction(txProxy);
    assertTrue(!this.txMgr.exists());

    this.txMgr.begin();
    TransactionId origId = this.txMgr.getTransactionId();
    assertTrue(this.txMgr.exists());
    {
      TXStateProxy tx = txMgrImpl.pauseTransaction();
      assertTrue(!this.txMgr.exists());
      assertThatThrownBy(() -> this.txMgr.begin()).isInstanceOf(IllegalStateException.class);
      assertTrue(!this.txMgr.exists());
      txMgrImpl.unpauseTransaction(tx);
    }
    assertTrue(this.txMgr.exists());
    assertEquals(origId, this.txMgr.getTransactionId());
    this.txMgr.rollback();
  }

  @Test
  public void testSuspendResume() {
    TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
    assertTrue(!this.txMgr.exists());
    assertEquals(null, txMgrImpl.pauseTransaction());
    TXStateProxy txProxy = null;
    txMgrImpl.unpauseTransaction(txProxy);
    assertTrue(!this.txMgr.exists());

    this.txMgr.begin();
    TransactionId origId = this.txMgr.getTransactionId();
    assertTrue(this.txMgr.exists());
    {
      TXStateProxy tx = txMgrImpl.internalSuspend();
      assertTrue(!this.txMgr.exists());
      this.txMgr.begin();
      try {
        txMgrImpl.internalResume(tx);
        fail("expected IllegalStateException");
      } catch (IllegalStateException expected) {
        LogService.getLogger().info("expected ", expected);
      }
      this.txMgr.rollback();
      assertTrue(!this.txMgr.exists());
      txMgrImpl.internalResume(tx);
    }
    assertTrue(this.txMgr.exists());
    assertEquals(origId, this.txMgr.getTransactionId());
    this.txMgr.rollback();
  }

  @Test
  public void testPublicSuspendResume() {
    CacheTransactionManager txMgr = this.txMgr;
    assertTrue(!this.txMgr.exists());
    assertEquals(null, txMgr.suspend());
    TransactionId txId = null;
    try {
      txMgr.resume(txId);
      fail("expected IllegalStateException");
    } catch (IllegalStateException e) {
    }
    assertTrue(!this.txMgr.exists());

    this.txMgr.begin();
    TransactionId origId = this.txMgr.getTransactionId();
    assertTrue(this.txMgr.exists());
    {
      TransactionId tx = txMgr.suspend();
      assertTrue(!this.txMgr.exists());
      this.txMgr.begin();
      try {
        txMgr.resume(tx);
        fail("expected IllegalStateException");
      } catch (IllegalStateException expected) {
      }
      this.txMgr.rollback();
      assertTrue(!this.txMgr.exists());
      txMgr.resume(tx);
    }
    assertTrue(this.txMgr.exists());
    assertEquals(origId, this.txMgr.getTransactionId());
    this.txMgr.rollback();

  }

  @Test
  public void testCheckNoTX() {
    {
      AttributesFactory<String, String> af = new AttributesFactory<>();
      af.setScope(Scope.GLOBAL);
      Region<String, String> gr = null;
      try {
        gr = this.cache.createRegion("GLOBALTXTest", af.create());
      } catch (CacheException ex) {
        fail("did not expect " + ex);
      }
      try {
        gr.put("foo", "bar1");
      } catch (Exception ex) {
        fail("did not expect " + ex);
      }
      this.txMgr.begin();
      try {
        gr.put("foo", "bar2");
        fail("expected UnsupportedOperationException");
      } catch (UnsupportedOperationException expected) {
      } catch (Exception ex) {
        fail("did not expect " + ex);
      }
      this.txMgr.rollback();
    }


    {
      DiskStoreFactory dsf = this.cache.createDiskStoreFactory();
      dsf.create("testCheckNoTX");
      AttributesFactory<String, String> af = new AttributesFactory<>();
      af.setScope(Scope.LOCAL);
      af.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
      af.setDiskStoreName("testCheckNoTX");
      Region<String, String> dr = null;
      try {
        dr = this.cache.createRegion("DiskTXTest", af.create());
      } catch (CacheException ex) {
        fail("did not expect " + ex);
      }
      try {
        try {
          dr.put("foo", "bar1");
        } catch (Exception ex) {
          fail("did not expect " + ex);
        }
        this.txMgr.begin();
        try {
          dr.put("foo", "bar2");
          fail("expected UnsupportedOperationException");
        } catch (UnsupportedOperationException expected) {
        } catch (Exception ex) {
          fail("did not expect " + ex);
        }
        this.txMgr.rollback();
      } finally {
        dr.localDestroyRegion();
      }
    }
  }

  @Test
  public void valuesRepeatableReadDoesNotIncludeTombstones() throws Exception {
    Region newRegion = createRegion("newRegion", true);
    newRegion.put("key1", "value1");
    newRegion.destroy("key1"); // creates a tombstone

    txMgr.begin(); // tx1
    newRegion.values().toArray(); // this is a repeatable read, does not read tombstone
    TransactionId txId = txMgr.suspend();

    txMgr.begin(); // tx2
    newRegion.put("key1", "newValue");
    txMgr.commit();

    txMgr.resume(txId);
    newRegion.put("key1", "value1");
    txMgr.commit();
    assertThat(newRegion.get("key1")).isEqualTo("value1");
  }

  @Test
  public void keySetRepeatableReadDoesNotIncludeTombstones() throws Exception {
    Region newRegion = createRegion("newRegion", true);
    newRegion.put("key1", "value1");
    newRegion.destroy("key1"); // creates a tombstone

    txMgr.begin(); // tx1
    newRegion.keySet().toArray(); // this is a repeatable read, does not read tombstone
    TransactionId txId = txMgr.suspend();

    txMgr.begin(); // tx2
    newRegion.put("key1", "newValue");
    txMgr.commit();

    txMgr.resume(txId);
    newRegion.put("key1", "value1");
    txMgr.commit();
    assertThat(newRegion.get("key1")).isEqualTo("value1");
  }

  @Test
  public void valuesRepeatableReadIncludesInvalidates() throws Exception {
    Region newRegion = createRegion("newRegion", true);
    newRegion.put("key1", "value1");
    newRegion.invalidate("key1");

    txMgr.begin(); // tx1
    newRegion.values().toArray(); // this is a repeatable read, reads invalidate
    TransactionId txId = txMgr.suspend();

    txMgr.begin(); // tx2
    newRegion.put("key1", "newValue");
    txMgr.commit();

    txMgr.resume(txId);
    newRegion.put("key1", "value1");
    assertThatThrownBy(() -> txMgr.commit()).isExactlyInstanceOf(CommitConflictException.class);
    assertThat(newRegion.get("key1")).isEqualTo("newValue");
  }

  @Test
  public void keySetRepeatableReadIncludesInvalidates() throws Exception {
    Region newRegion = createRegion("newRegion", true);
    newRegion.put("key1", "value1");
    newRegion.invalidate("key1");

    txMgr.begin(); // tx1
    newRegion.keySet().toArray(); // this is a repeatable read, reads invalidate
    TransactionId txId = txMgr.suspend();

    txMgr.begin(); // tx2
    newRegion.put("key1", "newValue");
    txMgr.commit();

    txMgr.resume(txId);
    newRegion.put("key1", "value1");
    assertThatThrownBy(() -> txMgr.commit()).isExactlyInstanceOf(CommitConflictException.class);
    assertThat(newRegion.get("key1")).isEqualTo("newValue");
  }

  @Test
  public void testRepeatableRead() throws CacheException {
    final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
    TXStateProxy tx;

    // try repeating a get and make sure it doesn't cause a conflict
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    assertEquals("value1", this.region.get("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);

    assertEquals("value1", this.region.get("key1"));
    txMgrImpl.commit();

    // try repeating a get and modify the entry and make sure it causes a conflict
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    assertEquals("value1", this.region.get("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals("value1", this.region.get("key1"));
    this.region.put("key1", "value3");
    assertEquals("value3", this.region.get("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // try repeating a getEntry and make sure it doesn't cause a conflict
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    this.region.getEntry("key1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);

    assertEquals("value1", this.region.get("key1"));
    txMgrImpl.commit();

    // try repeating a getEntry and modify the entry and make sure it causes a conflict
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    this.region.getEntry("key1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    this.region.put("key1", "value3");
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // try RR when entry fetched using entrySet
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    this.region.get("key1"); // bootstrap the tx, entrySet does not
    this.region.entrySet(false).iterator().next();
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);

    assertEquals("value1", this.region.get("key1"));
    txMgrImpl.commit();

    // try RRW->CONFLICT when entry fetched using entrySet
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    this.region.get("key1"); // bootstrap the tx, entrySet does not
    this.region.entrySet(false).iterator().next();
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals("value1", this.region.get("key1"));
    this.region.put("key1", "value3");
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // try containsKey
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    assertEquals(true, this.region.containsKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.remove("key1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(true, this.region.containsKey("key1"));
    txMgrImpl.commit();
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    assertEquals(true, this.region.containsKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.remove("key1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(true, this.region.containsKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsKey("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    // try containsValueForKey
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    assertEquals(true, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.remove("key1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(true, this.region.containsValueForKey("key1"));
    txMgrImpl.commit();
    this.region.put("key1", "value1"); // non-tx
    txMgrImpl.begin();
    assertEquals(true, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.remove("key1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(true, this.region.containsValueForKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsValueForKey("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // now try the same things but with no entry in committed state at
    // the time of the first read
    // try repeating a get and make sure it doesn't cause a conflict
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(null, this.region.get("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);

    assertEquals(null, this.region.get("key1"));
    txMgrImpl.commit();

    // try repeating a get and modify the entry and make sure it causes a conflict
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(null, this.region.get("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(null, this.region.get("key1"));
    this.region.put("key1", "value3");
    assertEquals("value3", this.region.get("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // try repeating a getEntry and make sure it doesn't cause a conflict
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(null, this.region.getEntry("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);

    assertEquals(null, this.region.getEntry("key1"));
    txMgrImpl.commit();

    // try repeating a getEntry and modify the entry and make sure it causes a conflict
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(null, this.region.getEntry("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(null, this.region.getEntry("key1"));
    this.region.put("key1", "value3");
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // try containsKey
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(false, this.region.containsKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(false, this.region.containsKey("key1"));
    txMgrImpl.commit();
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(false, this.region.containsKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(false, this.region.containsKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsKey("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // try containsValueForKey
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(false, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(false, this.region.containsValueForKey("key1"));
    txMgrImpl.commit();
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    assertEquals(false, this.region.containsValueForKey("key1"));
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(false, this.region.containsValueForKey("key1"));
    this.region.put("key1", "value3");
    assertEquals(true, this.region.containsValueForKey("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }

    // try an invalidate of an already invalid entry
    this.region.remove("key1"); // non-tx
    this.region.create("key1", null); // non-tx
    txMgrImpl.begin();
    this.region.get("key1");
    this.region.localInvalidate("key1"); // should be a noop since it is already invalid
    tx = txMgrImpl.pauseTransaction();
    this.region.remove("key1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    txMgrImpl.commit();
    assertEquals(false, this.region.containsKey("key1"));

    // make sure a noop invalidate is repeatable read
    this.region.remove("key1"); // non-tx
    this.region.create("key1", null); // non-tx
    txMgrImpl.begin();
    this.region.localInvalidate("key1"); // should be a noop since it is already invalid
    tx = txMgrImpl.pauseTransaction();
    this.region.remove("key1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(true, this.region.containsKey("key1"));
    assertEquals(false, this.region.containsValueForKey("key1"));
    txMgrImpl.commit();
    assertEquals(false, this.region.containsKey("key1"));

    // make sure a destroy that throws entryNotFound is repeatable read
    this.region.remove("key1"); // non-tx
    txMgrImpl.begin();
    try {
      this.region.localDestroy("key1");
      fail("expected EntryNotFoundException");
    } catch (EntryNotFoundException expected) {
    }
    tx = txMgrImpl.pauseTransaction();
    this.region.create("key1", "value1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(false, this.region.containsKey("key1"));
    txMgrImpl.commit();
    assertEquals(true, this.region.containsKey("key1"));
    this.region.remove("key1"); // non-tx

    // make sure a create that throws entryExists is repeatable read
    this.region.create("key1", "non-tx-value1"); // non-tx
    txMgrImpl.begin();
    try {
      this.region.create("key1", "value1");
      fail("expected EntryExistsException");
    } catch (EntryExistsException expected) {
    }
    tx = txMgrImpl.pauseTransaction();
    this.region.remove("key1"); // non-tx
    txMgrImpl.unpauseTransaction(tx);
    assertEquals(true, this.region.containsKey("key1"));
    txMgrImpl.commit();
    assertEquals(false, this.region.containsKey("key1"));
  }

  @Test
  public void testConflicts() throws CacheException {
    final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
    TXStateProxy tx;
    // try a put with no conflict to show that commit works
    txMgrImpl.begin();
    this.region.put("key1", "value1");
    txMgrImpl.commit();
    assertEquals("value1", this.region.get("key1"));
    this.region.localDestroy("key1");

    // now try a put with a conflict and make sure it is detected
    txMgrImpl.begin();
    this.region.put("key1", "value1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // do a non-tx put to force conflict
    txMgrImpl.unpauseTransaction(tx);
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("value2", this.region.get("key1"));
    this.region.localDestroy("key1");

    // slightly difference version where value already exists in cmt state
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.put("key1", "value1");
    txMgrImpl.commit();
    assertEquals("value1", this.region.get("key1"));
    this.region.localDestroy("key1");

    // now the conflict
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.put("key1", "value1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // do a non-tx put to force conflict
    txMgrImpl.unpauseTransaction(tx);
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("value2", this.region.get("key1"));
    this.region.localDestroy("key1");

    // now test create
    txMgrImpl.begin();
    this.region.create("key1", "value1");
    txMgrImpl.commit();
    assertEquals("value1", this.region.get("key1"));
    this.region.localDestroy("key1");

    // now try a create with a conflict and make sure it is detected
    txMgrImpl.begin();
    this.region.create("key1", "value1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // do a non-tx put to force conflict
    txMgrImpl.unpauseTransaction(tx);
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("value2", this.region.get("key1"));
    this.region.localDestroy("key1");

    // test localInvalidate
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.localInvalidate("key1");
    txMgrImpl.commit();
    assertTrue(this.region.containsKey("key1") && !this.region.containsValueForKey("key1"));
    this.region.localDestroy("key1");

    // now the conflict
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.localInvalidate("key1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // do a non-tx put to force conflict
    txMgrImpl.unpauseTransaction(tx);
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("value2", this.region.get("key1"));
    this.region.localDestroy("key1");

    // test invalidate
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.invalidate("key1");
    txMgrImpl.commit();
    assertTrue(this.region.containsKey("key1") && !this.region.containsValueForKey("key1"));
    this.region.localDestroy("key1");

    // now the conflict
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.invalidate("key1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // do a non-tx put to force conflict
    txMgrImpl.unpauseTransaction(tx);
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("value2", this.region.get("key1"));
    this.region.localDestroy("key1");

    // check C + DD is a NOOP that still gets conflict if non-tx entry created */
    this.txMgr.begin();
    this.region.create("newKey", "valueTX");
    tx = txMgrImpl.pauseTransaction();
    this.region.create("newKey", "valueNONTX");
    txMgrImpl.unpauseTransaction(tx);
    this.region.destroy("newKey");
    assertTrue(!this.region.containsKey("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("valueNONTX", this.region.get("newKey"));
    this.region.localDestroy("newKey");

    // check C + LD is a NOOP that still gets conflict if non-tx entry created */
    this.txMgr.begin();
    this.region.create("newKey", "valueTX");
    tx = txMgrImpl.pauseTransaction();
    this.region.create("newKey", "valueNONTX");
    txMgrImpl.unpauseTransaction(tx);
    this.region.localDestroy("newKey");
    assertTrue(!this.region.containsKey("key1"));
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("valueNONTX", this.region.get("newKey"));
    this.region.localDestroy("newKey");

    // test localDestroy
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.localDestroy("key1");
    txMgrImpl.commit();
    assertTrue(!this.region.containsKey("key1"));

    // now the conflict
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.localDestroy("key1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // do a non-tx put to force conflict
    txMgrImpl.unpauseTransaction(tx);
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("value2", this.region.get("key1"));
    this.region.localDestroy("key1");

    // test destroy
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.destroy("key1");
    txMgrImpl.commit();
    assertTrue(!this.region.containsKey("key1"));

    // now the conflict
    this.region.put("key1", "value0");
    txMgrImpl.begin();
    this.region.destroy("key1");
    tx = txMgrImpl.pauseTransaction();
    this.region.put("key1", "value2"); // do a non-tx put to force conflict
    txMgrImpl.unpauseTransaction(tx);
    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (CommitConflictException ex) {
    }
    assertEquals("value2", this.region.get("key1"));
    this.region.localDestroy("key1");

    checkUserAttributeConflict(txMgrImpl);

    // make sure non-tx local-invalidate followed by invalidate
    // does not cause conflict
    this.region.create("key1", "val1");
    this.region.localInvalidate("key1");
    txMgrImpl.begin();
    this.region.put("key1", "txVal1");
    tx = txMgrImpl.pauseTransaction();
    this.region.invalidate("key1");
    txMgrImpl.unpauseTransaction(tx);
    txMgrImpl.commit();
    assertEquals("txVal1", this.region.getEntry("key1").getValue());
    this.region.destroy("key1");

    // now try a put and a region destroy.
    txMgrImpl.begin();
    this.region.create("key1", "value1");
    TXStateProxy tis = txMgrImpl.pauseTransaction();
    this.region.localDestroyRegion(); // non-tx
    txMgrImpl.unpauseTransaction(tis);

    try {
      txMgrImpl.commit();
      fail("expected CommitConflictException");
    } catch (TransactionException ex) {
    }
  }

  protected void checkUserAttributeConflict(final CacheTransactionManager txMgrImpl) {
    { // now check entry user attribute conflict checking
      this.region.put("key1", "value0");
      Region.Entry cmtre = this.region.getEntry("key1");
      assertEquals(null, cmtre.getUserAttribute());
      txMgrImpl.begin();
      Region.Entry txre = this.region.getEntry("key1");
      txre.setUserAttribute("uaValue1");
      txMgrImpl.commit();
      assertEquals("uaValue1", cmtre.getUserAttribute());
      this.region.localDestroy("key1");

      this.region.put("key1", "value0");
      cmtre = this.region.getEntry("key1");
      assertEquals("value0", cmtre.getValue());
      assertEquals(null, cmtre.getUserAttribute());
      this.txMgr.begin();
      txre = this.region.getEntry("key1");
      assertEquals("value0", txre.getValue());
      this.region.put("key1", "valueTX");
      assertEquals("valueTX", txre.getValue());
      assertEquals("value0", cmtre.getValue());
      assertEquals(null, txre.getUserAttribute());
      txre.setUserAttribute("uaValue1");
      assertEquals("uaValue1", txre.getUserAttribute());
      assertEquals(null, cmtre.getUserAttribute());
      cmtre.setUserAttribute("uaValue2");
      assertEquals("uaValue2", cmtre.getUserAttribute());
      assertEquals("uaValue1", txre.getUserAttribute());
      try {
        txMgrImpl.commit();
        fail("expected CommitConflictException");
      } catch (CommitConflictException ex) {
      }
      try {
        txre.getValue();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txre.isDestroyed();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txre.getUserAttribute();
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      try {
        txre.setUserAttribute("foo");
        fail("expected IllegalStateException");
      } catch (IllegalStateException ok) {
      }
      assertEquals("uaValue2", cmtre.getUserAttribute());
      assertEquals("value0", cmtre.getValue());
      this.region.localDestroy("key1");
    }
  }

  @Test
  public void testNoopInvalidates() throws CacheException {
    final CachePerfStats stats = this.cache.getCachePerfStats();
    TransactionListener tl = new TransactionListenerAdapter() {
      @Override
      public void afterRollback(TransactionEvent event) {
        te = event;
      }
    };
    this.txMgr.addListener(tl);
    // Make sure invalidates done on invalid entries are noops

    { // distributed invalidate
      // first make sure invalidate is counted as a change
      int txRollbackChanges = stats.getTxRollbackChanges();
      this.region.create("key1", "value1");
      this.txMgr.begin();
      this.region.invalidate("key1");
      this.txMgr.rollback();
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      assertEquals(1, te.getEvents().size());
      this.region.destroy("key1");

      this.region.create("key1", "value1");
      this.txMgr.begin();
      this.region.invalidate("key1");
      this.txMgr.commit();
      assertEquals(1, te.getEvents().size());
      this.region.destroy("key1");

      // now make sure a committed entry that is invalid is not counted as a change
      txRollbackChanges = stats.getTxRollbackChanges();
      this.region.create("key1", "value1");
      this.region.invalidate("key1");
      this.txMgr.begin();
      this.region.invalidate("key1");
      this.txMgr.rollback();
      assertEquals(txRollbackChanges, stats.getTxRollbackChanges());
      assertEquals(0, te.getEvents().size());
      this.region.destroy("key1");

      this.region.create("key1", "value1");
      this.region.invalidate("key1");
      this.txMgr.begin();
      this.region.invalidate("key1");
      this.txMgr.commit();
      assertEquals(0, te.getEvents().size());
      this.region.destroy("key1");

      // now make sure that multiple invalidates of same entry are a single change
      txRollbackChanges = stats.getTxRollbackChanges();
      this.region.create("key1", "value1");
      this.txMgr.begin();
      this.region.invalidate("key1");
      this.region.invalidate("key1");
      this.region.invalidate("key1");
      this.txMgr.rollback();
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      assertEquals(1, te.getEvents().size());
      this.region.destroy("key1");

      this.region.create("key1", "value1");
      this.txMgr.begin();
      this.region.invalidate("key1");
      this.region.invalidate("key1");
      this.region.invalidate("key1");
      this.txMgr.commit();
      assertEquals(1, te.getEvents().size());
      this.region.destroy("key1");
    }

    { // local invalidate
      // first make sure invalidate is counted as a change
      int txRollbackChanges = stats.getTxRollbackChanges();
      this.region.create("key1", "value1");
      this.txMgr.begin();
      this.region.localInvalidate("key1");
      this.txMgr.rollback();
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      this.region.destroy("key1");

      // now make sure a committed entry that is invalid is not counted as a change
      txRollbackChanges = stats.getTxRollbackChanges();
      this.region.create("key1", "value1");
      this.region.localInvalidate("key1");
      this.txMgr.begin();
      this.region.localInvalidate("key1");
      this.txMgr.rollback();
      assertEquals(txRollbackChanges, stats.getTxRollbackChanges());
      this.region.destroy("key1");

      // now make sure that multiple localInvalidates of same entry are a single change
      txRollbackChanges = stats.getTxRollbackChanges();
      this.region.create("key1", "value1");
      this.txMgr.begin();
      this.region.localInvalidate("key1");
      this.region.localInvalidate("key1");
      this.region.localInvalidate("key1");
      this.txMgr.rollback();
      assertEquals(txRollbackChanges + 1, stats.getTxRollbackChanges());
      this.region.destroy("key1");
    }
  }

  private static void clearRegion(Region r) throws TimeoutException {
    Iterator kI = r.keySet().iterator();
    try {
      while (kI.hasNext()) {
        r.destroy(kI.next());
      }
    } catch (CacheException ce) {
      fail("clearRegion operation failed");
    }
  }

  private static final int LRUENTRY_NULL = 0;
  private static final int LRUENTRY_STRING = 1;
  private static final int LRUENTRY_INTEGER = 2;
  private static final int LRUENTRY_LONG = 3;
  private static final int LRUENTRY_DOUBLE = 4;

  private static void assertLRUEntries(Set entries, int size, String keyPrefix, int instanceId) {
    assertEquals(size, entries.size());
    Iterator entItr = entries.iterator();
    while (entItr.hasNext()) {
      Region.Entry re = (Region.Entry) entItr.next();
      switch (instanceId) {
        case LRUENTRY_NULL:
          assertNull(re.getValue());
          break;
        case LRUENTRY_STRING:
          assertTrue(re.getValue() instanceof String);
          break;
        case LRUENTRY_INTEGER:
          assertTrue(re.getValue() instanceof Integer);
          break;
        case LRUENTRY_LONG:
          assertTrue(re.getValue() instanceof Long);
          break;
        case LRUENTRY_DOUBLE:
          assertTrue(re.getValue() instanceof Double);
          break;
        default:
          fail("Unknown instance type in assertLRUEntries: " + instanceId);
      }
      String reKey = (String) re.getKey();
      assertTrue("expected " + reKey + " to start with " + keyPrefix, reKey.startsWith(keyPrefix));
    }
  }

  @Test
  public void testEviction() throws CacheException {
    final int lruSize = 8;
    AttributesFactory<String, Object> af = new AttributesFactory<>();
    af.setEvictionAttributes(
        EvictionAttributes.createLRUEntryAttributes(lruSize, EvictionAction.LOCAL_DESTROY));
    af.setScope(Scope.LOCAL);
    Region<String, Object> lruRegion = this.cache.createRegion(getUniqueName(), af.create());

    // Non-TX LRU verification
    assertEquals(0, lruRegion.entrySet(false).size());
    int numToPut = lruSize + 2;
    for (int i = 0; i < numToPut; ++i) {
      lruRegion.put("key" + i, new Integer(i));
    }
    assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
    clearRegion(lruRegion);

    // TX LRU verification
    assertEquals(0, lruRegion.entrySet(false).size());
    numToPut = lruSize + 2;
    this.txMgr.begin();
    for (int i = 0; i < numToPut; ++i) {
      lruRegion.put("key" + i, new Long(i));
    }
    assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
    this.txMgr.commit();
    assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_LONG);
    clearRegion(lruRegion);

    // TX/non-TX no conflict verification w/ initial state
    // full+2, all committed entries have TX refs
    {
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TXStateProxy tx;
      numToPut = lruSize + 2;
      assertEquals(0, lruRegion.entrySet(false).size());
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.create("key" + i, new Integer(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      this.txMgr.begin();
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, new Long(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
      tx = txMgrImpl.pauseTransaction();

      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("non-tx key" + i, new Integer(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
      assertNull(lruRegion.get("non-tx key0"));

      txMgrImpl.unpauseTransaction(tx);
      this.txMgr.commit();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_LONG);
    }
    clearRegion(lruRegion);

    // TX/non-TX no conflict verification w/ invalid initial state
    // full+2, all committed entries have TX refs using a loader
    {
      AttributesMutator<String, Object> mutator = lruRegion.getAttributesMutator();
      mutator.setCacheLoader(new CacheLoader() {
        // int count = 0;
        @Override
        public Object load(LoaderHelper helper) throws CacheLoaderException {
          return "value" + helper.getArgument();
        }

        @Override
        public void close() {}
      });
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TXStateProxy tx;
      numToPut = lruSize + 2;
      assertEquals(0, lruRegion.entrySet(false).size());
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.create("key" + i, null);
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_NULL);
      // assertIndexDetailsEquals(lruSize, lruRegion.entrySet(false).size());
      this.txMgr.begin();
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.get("key" + i, new Integer(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_STRING);
      tx = txMgrImpl.pauseTransaction();

      assertEquals(lruSize, lruRegion.entrySet(false).size());
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_NULL);
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.get("non-tx key" + i, new Integer(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_NULL);
      assertNull(lruRegion.getEntry("non-tx key0"));

      txMgrImpl.unpauseTransaction(tx);
      this.txMgr.commit();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_STRING);
      Iterator it = lruRegion.keySet().iterator();
      while (it.hasNext()) {
        lruRegion.localInvalidate(it.next(), null);
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_NULL);
      mutator.setCacheLoader(null);
    }
    clearRegion(lruRegion);

    // TX/TX/non-TX no conflict verification w/ initial state full, TX
    // add lruLimit+4, existing committed have TX 2 refs, force non-TX
    // eviction, force TX eviction
    {
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TransactionId txId1, txId2;
      numToPut = lruSize + 4;
      assertEquals(0, lruRegion.entrySet(false).size());
      // Create entries
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.create("key" + i, new Integer(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      this.txMgr.begin();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
      // Add a TX reference to committed entries, add a few on top of that
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, new Long(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
      txId1 = txMgrImpl.suspend();

      this.txMgr.begin();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
      // Add another TX reference to committed entries, add a few on top of that
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, new Double(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_DOUBLE);
      txId2 = txMgrImpl.suspend();

      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      // Force the Non-Tx "put" to remove each attempt since region is full
      // and all the committed entries are currently part of a TX
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("non-tx key" + i, new Integer(i));
      }
      assertTrue(numToPut > lruSize);
      assertNull(lruRegion.get("non-tx key0"));
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      txMgrImpl.resume(txId1);
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
      // Check to make sure no conflict was caused by non-TX put evictions
      // This should remove all references for each committed entry
      this.txMgr.commit();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_LONG);
      txMgrImpl.resume(txId2);
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_DOUBLE);
      this.txMgr.rollback();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_LONG);

      // Test to make sure we can evict something that has been rolled back
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, "value" + i);
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_STRING);
    }
    clearRegion(lruRegion);

    // TX/non-TX no conflict verification w/ initial state full, TX
    // add lruLimit+4, force non-TX eviction, then rolls back, make
    // sure that non-TX eviction works properly
    {
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TXStateProxy tx;
      numToPut = lruSize + 4;
      assertEquals(0, lruRegion.entrySet(false).size());
      // Create entries
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.create("key" + i, new Integer(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      this.txMgr.begin();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
      // Add a TX reference to committed entries, add a few on top of that
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, new Long(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
      tx = txMgrImpl.pauseTransaction();

      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
      // Force the Non-Tx "put" to remove each attempt since region is full
      // and all the committed entries are currently part of a TX
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("non-tx key" + i, new Integer(i));
      }
      assertNull(lruRegion.get("non-tx key0"));
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      txMgrImpl.unpauseTransaction(tx);
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
      // This should remove all references for each committed entry
      this.txMgr.rollback();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      // Test to make sure we can evict something that has been rolled back
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, "value" + i);
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_STRING);
    }
    clearRegion(lruRegion);

    // TX/TX conflict with initial state full, TX
    // add lruLimit+4, after failed commit make
    // sure that non-TX eviction works properly
    {
      final TXManagerImpl txMgrImpl = (TXManagerImpl) this.txMgr;
      TXStateProxy tx;
      numToPut = lruSize + 4;
      assertEquals(0, lruRegion.entrySet(false).size());
      // Create entries
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.create("key" + i, new Integer(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      this.txMgr.begin();
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);
      // Add a TX reference to committed entries, add a few on top of that
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, new Long(i));
      }
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
      tx = txMgrImpl.pauseTransaction();

      // Cause a conflict
      lruRegion.put("key" + (numToPut - 1), new Integer(numToPut - 1));

      txMgrImpl.unpauseTransaction(tx);
      assertLRUEntries(lruRegion.entrySet(false), numToPut, "key", LRUENTRY_LONG);
      // This should remove all references for each committed entry
      try {
        this.txMgr.commit();
        fail("Expected CommitConflictException during commit LRU Eviction test!");
      } catch (CommitConflictException ok) {
      }

      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_INTEGER);

      // Test to make sure we can evict something that has been rolled back
      for (int i = 0; i < numToPut; ++i) {
        lruRegion.put("key" + i, "value" + i);
      }
      assertLRUEntries(lruRegion.entrySet(false), lruSize, "key", LRUENTRY_STRING);
    }

    lruRegion.localDestroyRegion();
  }

  @Test
  public void testJTASynchronization()
      throws CacheException, javax.transaction.NotSupportedException,
      javax.transaction.RollbackException, javax.transaction.SystemException,
      javax.transaction.HeuristicMixedException, javax.transaction.HeuristicRollbackException {

    javax.transaction.TransactionManager jtaTxMgr = this.cache.getJTATransactionManager();
    TransactionListener tl = new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        ++listenerAfterCommit;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        ++listenerAfterFailedCommit;
        te = event;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        ++listenerAfterRollback;
        te = event;
      }

      @Override
      public void close() {
        ++listenerClose;
      }
    };

    this.txMgr.addListener(tl);
    Synchronization gfTXSync;

    // Test successful JTA commit
    jtaTxMgr.begin();
    this.txMgr.begin();
    {
      TXManagerImpl gfTxMgrImpl = (TXManagerImpl) this.txMgr;
      gfTXSync = gfTxMgrImpl.getTXState();
    }
    jtaTxMgr.getTransaction().registerSynchronization(gfTXSync);
    assertEquals(0, this.listenerAfterCommit);
    this.cache.getLogger().info("SWAP:doingCreate");
    this.region.create("syncKey1", "syncVal1");
    jtaTxMgr.commit();
    assertEquals(1, this.listenerAfterCommit);
    assertEquals("syncVal1", this.region.getEntry("syncKey1").getValue());

    try {
      this.txMgr.commit();
      fail("JTA Cache Manager should have called commit!");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable expected) {
    }

    // Test JTA rollback
    jtaTxMgr.begin();
    this.txMgr.begin();
    {
      TXManagerImpl gfTxMgrImpl = (TXManagerImpl) this.txMgr;
      gfTXSync = gfTxMgrImpl.getTXState();
    }
    jtaTxMgr.getTransaction().registerSynchronization(gfTXSync);
    assertEquals(0, this.listenerAfterRollback);
    this.region.put("syncKey2", "syncVal2");
    jtaTxMgr.rollback();
    assertEquals(1, this.listenerAfterRollback);
    assertTrue(!this.region.containsKey("syncKey2"));

    // Test failed JTA commit with suspend
    jtaTxMgr.begin();
    this.txMgr.begin();
    {
      TXManagerImpl gfTxMgrImpl = (TXManagerImpl) this.txMgr;
      gfTXSync = gfTxMgrImpl.getTXState();
      jtaTxMgr.getTransaction().registerSynchronization(gfTXSync);
      assertEquals(0, this.listenerAfterFailedCommit);
      this.region.put("syncKey3", "syncVal3");
      assertEquals("syncVal3", this.region.getEntry("syncKey3").getValue());

      TXStateProxy gfTx = gfTxMgrImpl.pauseTransaction();
      javax.transaction.Transaction jtaTx = jtaTxMgr.suspend();
      assertNull(jtaTxMgr.getTransaction());
      this.region.put("syncKey3", "syncVal4");
      assertEquals("syncVal4", this.region.getEntry("syncKey3").getValue());
      gfTxMgrImpl.unpauseTransaction(gfTx);
      try {
        jtaTxMgr.resume(jtaTx);
      } catch (Exception failure) {
        fail("JTA resume failed");
      }
      assertNotNull(jtaTxMgr.getTransaction());
    }
    assertEquals("syncVal3", this.region.getEntry("syncKey3").getValue());
    try {
      jtaTxMgr.commit();
      fail("Expected JTA manager conflict exception!");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable expected) {
    }
    assertEquals(1, this.listenerAfterFailedCommit);
    assertEquals("syncVal4", this.region.getEntry("syncKey3").getValue());


    // Test failed JTA commit with a new thread
    jtaTxMgr.begin();
    this.txMgr.begin();
    {
      TXManagerImpl gfTxMgrImpl = (TXManagerImpl) this.txMgr;
      gfTXSync = gfTxMgrImpl.getTXState();
      jtaTxMgr.getTransaction().registerSynchronization(gfTXSync);
      assertEquals(1, this.listenerAfterFailedCommit);
      this.region.put("syncKey4", "syncVal3");
      assertEquals("syncVal3", this.region.getEntry("syncKey4").getValue());

      // Create a new thread and have it update the same key, causing
      // a conflict
      final int signal[] = {0};
      Thread t = new Thread("non-TX conflict generator") {
        @Override
        public void run() {
          try {
            region.put("syncKey4", "syncVal4");
            while (true)
              synchronized (signal) {
                signal[0] = 1;
                signal.notify();
                signal.wait();
                if (signal[0] == 0) {
                  break;
                }
              }
          } catch (Exception error) {
            fail("Non-tx thread failure due to: " + error);
          }
        }
      };
      t.start();
      try {
        while (true)
          synchronized (signal) {
            if (signal[0] == 1) {
              signal[0] = 0;
              signal.notify();
              break;
            } else {
              signal.wait();
            }
          }
      } catch (InterruptedException dangit) {
        fail("Tx thread waiting for non-tx thread failed due to : " + dangit);
      }
      assertEquals("syncVal3", this.region.getEntry("syncKey4").getValue());
    }
    try {
      jtaTxMgr.commit();
      fail("Expected JTA manager conflict exception!");
    } catch (javax.transaction.HeuristicRollbackException expected) {
    } catch (javax.transaction.RollbackException alsoExpected) {
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable yuk) {
      fail("Did not expect this throwable from JTA commit: " + yuk);
    }
    assertEquals(2, this.listenerAfterFailedCommit);
    assertEquals("syncVal4", this.region.getEntry("syncKey4").getValue());

    this.txMgr.removeListener(tl);
  }

  @Test
  public void testJTAEnlistment() throws CacheException, javax.transaction.NotSupportedException,
      javax.transaction.RollbackException, javax.transaction.SystemException,
      javax.transaction.HeuristicMixedException, javax.transaction.HeuristicRollbackException {

    TransactionListener tl = new TransactionListener() {
      @Override
      public void afterCommit(TransactionEvent event) {
        ++listenerAfterCommit;
        te = event;
      }

      @Override
      public void afterFailedCommit(TransactionEvent event) {
        ++listenerAfterFailedCommit;
        te = event;
      }

      @Override
      public void afterRollback(TransactionEvent event) {
        ++listenerAfterRollback;
        te = event;
      }

      @Override
      public void close() {
        ++listenerClose;
      }
    };

    this.txMgr.addListener(tl);

    javax.transaction.UserTransaction userTx = null;
    try {
      userTx = (javax.transaction.UserTransaction) this.cache.getJNDIContext()
          .lookup("java:/UserTransaction");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable badDog) {
      fail("Expected to get a healthy UserTransaction!");
    }

    // Test enlistment for put
    // Test enlisted rollback
    // Test prevention of rollback/commit for enlisted transaction
    assertEquals(0, this.listenerAfterRollback);
    userTx.begin();
    this.region.put("enlistKey", "enlistVal");
    assertEquals("enlistVal", this.region.getEntry("enlistKey").getValue());
    assertNotNull(this.txMgr.getTransactionId());
    try {
      this.txMgr.rollback();
      fail("Should not allow a CacheTransactionManager.rollback call once the GF Tx is enlisted");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable ok) {
    }

    try {
      this.txMgr.commit();
      fail("Should not allow a CacheTransactionManager.commit() call once the GF Tx is enlisted");
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable alsoOk) {
    }
    userTx.rollback();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(!this.region.containsKey("enlistKey"));
    assertEquals(1, this.listenerAfterRollback);

    // Test enlistment for create
    // Test commit
    assertEquals(0, this.listenerAfterCommit);
    userTx.begin();
    this.region.create("enlistKey", "enlistVal");
    assertEquals("enlistVal", this.region.getEntry("enlistKey").getValue());
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(this.region.containsKey("enlistKey"));
    assertEquals("enlistVal", this.region.getEntry("enlistKey").getValue());
    assertEquals(1, this.listenerAfterCommit);

    // Test enlistment for get
    assertEquals(1, this.listenerAfterCommit);
    userTx.begin();
    assertEquals("enlistVal", this.region.get("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertEquals(2, this.listenerAfterCommit);

    // Test enlistment for invalidate
    assertEquals(2, this.listenerAfterCommit);
    userTx.begin();
    this.region.invalidate("enlistKey");
    assertTrue(this.region.containsKey("enlistKey"));
    assertTrue(!this.region.containsValueForKey("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(this.region.containsKey("enlistKey"));
    assertTrue(!this.region.containsValueForKey("enlistKey"));
    assertEquals(3, this.listenerAfterCommit);

    // Test enlistment for destroy
    assertEquals(3, this.listenerAfterCommit);
    userTx.begin();
    this.region.destroy("enlistKey");
    assertTrue(!this.region.containsKey("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(!this.region.containsKey("enlistKey"));
    assertEquals(4, this.listenerAfterCommit);

    // Test enlistment for load
    AttributesMutator<String, String> mutator = this.region.getAttributesMutator();
    mutator.setCacheLoader(new CacheLoader<String, String>() {
      int count = 0;

      @Override
      public String load(LoaderHelper helper) throws CacheLoaderException {
        return String.valueOf(count++);
      }

      @Override
      public void close() {}
    });
    assertEquals(4, this.listenerAfterCommit);
    userTx.begin();
    assertEquals("0", this.region.get("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    userTx.commit();
    assertNull(this.txMgr.getTransactionId());
    assertTrue(this.region.containsKey("enlistKey"));
    assertEquals("0", this.region.getEntry("enlistKey").getValue());
    assertEquals(5, this.listenerAfterCommit);
    mutator.setCacheLoader(null);

    // Test enlisted failed commit
    assertEquals(0, this.listenerAfterFailedCommit);
    userTx.begin();
    this.region.put("enlistKey", "enlistVal");
    assertEquals("enlistVal", this.region.get("enlistKey"));
    assertNotNull(this.txMgr.getTransactionId());
    {
      TXManagerImpl gfTxMgrImpl = (TXManagerImpl) this.txMgr;
      TXStateProxy gfTx = gfTxMgrImpl.pauseTransaction();

      javax.transaction.TransactionManager jtaTxMgr = this.cache.getJTATransactionManager();
      javax.transaction.Transaction jtaTx = jtaTxMgr.suspend();

      this.region.put("enlistKey", "conflictVal");
      assertEquals("conflictVal", this.region.get("enlistKey"));

      try {
        jtaTxMgr.resume(jtaTx);
      } catch (Exception failure) {
        fail("JTA resume failed");
      }
      gfTxMgrImpl.unpauseTransaction(gfTx);
    }
    assertEquals("enlistVal", this.region.get("enlistKey"));
    try {
      userTx.commit();
      fail("Expected JTA commit exception!");
    } catch (javax.transaction.HeuristicRollbackException expected) {
    } catch (javax.transaction.RollbackException alsoExpected) {
    } catch (Exception yuk) {
      fail("Did not expect this exception from JTA commit: " + yuk);
    }
    assertNull(this.txMgr.getTransactionId());
    assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
    assertEquals(1, this.listenerAfterFailedCommit);

    // Test rollbackOnly UserTransaction enlistment
    userTx.begin();
    assertNull(this.txMgr.getTransactionId());
    userTx.setRollbackOnly();
    assertEquals(javax.transaction.Status.STATUS_MARKED_ROLLBACK, userTx.getStatus());
    try {
      this.region.put("enlistKey", "enlistVal2");
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertNull(this.txMgr.getTransactionId());
    try {
      assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertTrue(!this.region.containsKey("enlistKey2"));
    try {
      this.region.put("enlistKey2", "enlistVal3");
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertNull(this.txMgr.getTransactionId());
    try {
      assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
      fail("Expected to get a FailedSynchronizationException!");
    } catch (FailedSynchronizationException okay) {
    }
    assertTrue(!this.region.containsKey("enlistKey2"));
    userTx.rollback();
    assertEquals("conflictVal", this.region.getEntry("enlistKey").getValue());
    assertTrue(!this.region.containsKey("enlistKey2"));

    this.txMgr.removeListener(tl);
  }

  private static void waitForUpdates(final Index idx, final int expectedUpdates) {
    // DistributedTestCase.WaitCriterion wc = new DistributedTestCase.WaitCriterion() {
    // String excuse;
    // public boolean done() {
    // return idx.getStatistics().getNumUpdates() == expectedUpdates;
    // }
    //
    // public String description() {
    // return "expectedUpdates " + expectedUpdates + " but got this "
    // + idx.getStatistics().getNumUpdates();
    // }
    // };
    // DistributedTestCase.waitForCriterion(wc, 15 * 1000, 20, true);

    boolean done = false;
    try {
      for (StopWatch time = new StopWatch(true); !done
          && time.elapsedTimeMillis() < 15 * 1000; done =
              (idx.getStatistics().getNumUpdates() == expectedUpdates)) {
        Thread.sleep(20);
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    assertTrue("expectedUpdates " + expectedUpdates + " but got this "
        + idx.getStatistics().getNumUpdates(), done);
  }

  private static void waitForKeys(final Index idx, final int expectedKeys) {
    // DistributedTestCase.WaitCriterion wc = new DistributedTestCase.WaitCriterion() {
    // String excuse;
    // public boolean done() {
    // return idx.getStatistics().getNumberOfKeys() == expectedKeys;
    // }
    //
    // public String description() {
    // return "expectedKeys " + expectedKeys + " but got this "
    // + idx.getStatistics().getNumberOfKeys();
    // }
    // };
    // DistributedTestCase.waitForCriterion(wc, 15 * 1000, 20, true);

    boolean done = false;
    try {
      for (StopWatch time = new StopWatch(true); !done
          && time.elapsedTimeMillis() < 15 * 1000; done =
              (idx.getStatistics().getNumberOfKeys() == expectedKeys)) {
        Thread.sleep(20);
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    assertTrue(
        "expectedKeys " + expectedKeys + " but got this " + idx.getStatistics().getNumberOfKeys(),
        done);
  }

  @Test
  public void testTXAndQueries() throws CacheException, QueryException {
    IndexManager.TEST_RANGEINDEX_ONLY = true;
    try {
      final QueryService qs = this.cache.getQueryService();

      final String fromClause = this.region.getFullPath() + " value ";
      final String qstr = "SELECT DISTINCT * FROM " + fromClause;

      // Create a region with async index updates
      AttributesFactory af = new AttributesFactory(this.region.getAttributes());
      af.setIndexMaintenanceSynchronous(false);
      final Region aIregion = this.cache.createRegion(getUniqueName(), af.create());
      final String aIfromClause = aIregion.getFullPath() + " value ";
      final String aIqstr = "SELECT DISTINCT * FROM " + aIfromClause;

      // Confirm base functionality for query results
      this.region.put("qkey0", "qval0");
      this.region.put("qkey1", "qval01");
      Query q = qs.newQuery(qstr);
      SelectResults res = (SelectResults) q.execute();
      assertEquals(2, res.size());
      String val;
      for (Iterator resI = res.iterator(); resI.hasNext();) {
        val = (String) resI.next();
        assertTrue("Value: " + val + " does not start with qval", val.startsWith("qval"));
      }
      q = qs.newQuery(qstr + " where value.length > 6");
      res = (SelectResults) q.execute();
      assertEquals(0, res.size());

      aIregion.put("qkey0", "qval0");
      aIregion.put("qkey1", "qval01");
      q = qs.newQuery(aIqstr);
      res = (SelectResults) q.execute();
      assertEquals(2, res.size());
      for (Iterator resI = res.iterator(); resI.hasNext();) {
        val = (String) resI.next();
        assertTrue("Value: " + val + " does not start with qval", val.startsWith("qval"));
      }
      q = qs.newQuery(qstr + " where value.length > 6");
      res = (SelectResults) q.execute();
      assertEquals(0, res.size());

      // Test query results in a transaction
      this.txMgr.begin();
      Query q1 = qs.newQuery(qstr);
      this.region.put("noQkey2", "noQval2");
      res = (SelectResults) q1.execute();
      assertEquals(2, res.size());
      for (Iterator resI = res.iterator(); resI.hasNext();) {
        val = (String) resI.next();
        assertTrue("Value: " + val + " does not start with qval", val.startsWith("qval"));
      }
      Query aIq1 = qs.newQuery(aIqstr);
      aIregion.put("noQkey2", "noQval2");
      res = (SelectResults) aIq1.execute();
      assertEquals(2, res.size());
      for (Iterator resI = res.iterator(); resI.hasNext();) {
        val = (String) resI.next();
        assertTrue("Value: " + val + " does not start with qval", val.startsWith("qval"));
      }
      Query q2 = qs.newQuery(qstr + " where value.length > 6");
      res = (SelectResults) q2.execute();
      assertEquals(0, res.size());
      Query aIq2 = qs.newQuery(aIqstr + " where value.length > 6");
      res = (SelectResults) aIq2.execute();
      assertEquals(0, res.size());
      this.txMgr.commit();
      res = (SelectResults) q1.execute();
      assertEquals(3, res.size());
      res = (SelectResults) q2.execute();
      assertEquals(1, res.size());
      res = (SelectResults) aIq1.execute();
      assertEquals(3, res.size());
      res = (SelectResults) aIq2.execute();
      assertEquals(1, res.size());

      this.region.destroy("noQkey2");
      aIregion.destroy("noQkey2");

      // Confirm base functionality for index creation
      Index index0 = qs.createIndex("TXIndex0", IndexType.FUNCTIONAL, "value.length", fromClause);
      assertEquals(2, index0.getStatistics().getNumberOfKeys());
      assertEquals(2, index0.getStatistics().getNumberOfValues());
      assertEquals(2, index0.getStatistics().getNumUpdates()); // Shouldn't this be zero?
      Index aIindex0 =
          qs.createIndex("aITXIndex0", IndexType.FUNCTIONAL, "value.length", aIfromClause);
      assertEquals(2, aIindex0.getStatistics().getNumberOfKeys());
      assertEquals(2, aIindex0.getStatistics().getNumberOfValues());
      assertEquals(2, aIindex0.getStatistics().getNumUpdates()); // Shouldn't this be zero?
      q = qs.newQuery(qstr);
      res = (SelectResults) q.execute();
      assertEquals(2, res.size());
      assertEquals(0, index0.getStatistics().getTotalUses());
      aIq1 = qs.newQuery(aIqstr);
      res = (SelectResults) aIq1.execute();
      assertEquals(2, res.size());
      assertEquals(0, aIindex0.getStatistics().getTotalUses());

      final String val2 = "qval000002";
      this.region.put("qkey2", val2);
      assertEquals(3, index0.getStatistics().getNumUpdates()); // Shouldn't this be 1?
      assertEquals(3, index0.getStatistics().getNumberOfKeys());
      assertEquals(3, index0.getStatistics().getNumberOfValues());
      aIregion.put("qkey2", val2);
      final IndexManager.IndexUpdaterThread upThread =
          ((AbstractRegion) aIregion).getIndexManager().getUpdaterThread();
      while (!upThread.isDone()) {
        pause(20);
      }
      // @todo asif: for some reason the value returned by getNumberOfKeys is unstable.
      // Even when the code waits for it to be the expected value it intermittently
      // will fail because it never gets to be the expected value.
      // This stat (in RangeIndex at least) is only updated when we add a new key
      // to the valueToEntriesMap. I do not see a place that we ever remove from
      // this map (even when we do a removeMapping).
      waitForUpdates(aIindex0, 3);
      waitForKeys(aIindex0, 3);
      assertEquals(3, aIindex0.getStatistics().getNumUpdates()); // Shouldn't this be 1?
      assertEquals(3, aIindex0.getStatistics().getNumberOfKeys());
      assertEquals(3, aIindex0.getStatistics().getNumberOfValues());
      q = qs.newQuery("ELEMENT(" + qstr + " where value.length > 6)");
      assertEquals(val2, (String) q.execute());
      assertEquals(1, index0.getStatistics().getTotalUses());
      aIq1 = qs.newQuery("ELEMENT(" + aIqstr + " where value.length > 6)");
      assertEquals(val2, (String) aIq1.execute());

      this.region.destroy("qkey2");
      waitForKeys(index0, 2);
      assertEquals(2, index0.getStatistics().getNumberOfKeys()); // Shouldn't this be 1, again?
      assertEquals(2, index0.getStatistics().getNumberOfValues());
      assertEquals(4, index0.getStatistics().getNumUpdates());
      aIregion.destroy("qkey2");
      while (!upThread.isDone()) {
        pause(20);
      }
      waitForUpdates(aIindex0, 4);
      // waitForKeys(aIindex0, 3);
      // assertIndexDetailsEquals(3, aIindex0.getStatistics().getNumberOfKeys()); // Shouldn't this
      // be 1, again?
      assertEquals(2, aIindex0.getStatistics().getNumberOfValues());
      assertEquals(4, aIindex0.getStatistics().getNumUpdates());

      // Test index creation
      this.txMgr.begin();
      this.region.destroy("qkey1");
      this.region.put("noQkey3", "noQval3");
      Index index1 = qs.createIndex("TXIndex1", IndexType.FUNCTIONAL, "value", fromClause);
      assertEquals(2, index1.getStatistics().getNumberOfKeys());
      assertEquals(2, index1.getStatistics().getNumberOfValues());
      assertEquals(2, index1.getStatistics().getNumUpdates());
      assertEquals(2, index0.getStatistics().getNumberOfKeys());
      assertEquals(2, index0.getStatistics().getNumberOfValues());
      assertEquals(4, index0.getStatistics().getNumUpdates());

      aIregion.destroy("qkey1");
      aIregion.put("noQkey3", "noQval3");
      Index aIindex1 = qs.createIndex("aITXIndex1", IndexType.FUNCTIONAL, "value", aIfromClause);
      while (!upThread.isDone()) {
        pause(20);
      }
      waitForUpdates(aIindex0, 4);
      waitForUpdates(aIindex1, 2);
      // waitForKeys(aIindex0, 3);
      // waitForKeys(aIindex1, 2);
      assertEquals(2, aIindex1.getStatistics().getNumberOfKeys());
      assertEquals(2, aIindex1.getStatistics().getNumberOfValues());
      assertEquals(2, aIindex1.getStatistics().getNumUpdates());
      // assertIndexDetailsEquals(3, aIindex0.getStatistics().getNumberOfKeys());
      assertEquals(2, aIindex0.getStatistics().getNumberOfValues());
      assertEquals(4, aIindex0.getStatistics().getNumUpdates());


      q = qs.newQuery(qstr);
      res = (SelectResults) q.execute();
      assertEquals(2, res.size());
      assertEquals(0, index1.getStatistics().getTotalUses());
      assertEquals(1, index0.getStatistics().getTotalUses());

      aIq1 = qs.newQuery(aIqstr);
      res = (SelectResults) aIq1.execute();
      assertEquals(2, res.size());
      assertEquals(0, aIindex1.getStatistics().getTotalUses());
      assertEquals(1, aIindex0.getStatistics().getTotalUses());

      q = qs.newQuery(qstr + " where value < 'q'");
      res = (SelectResults) q.execute();
      assertEquals(1, index1.getStatistics().getTotalUses());
      assertEquals(0, res.size());

      aIq1 = qs.newQuery(aIqstr + " where value < 'q'");
      res = (SelectResults) aIq1.execute();
      assertEquals(1, aIindex1.getStatistics().getTotalUses());
      assertEquals(0, res.size());

      this.region.put("noQkey4", "noQval4");
      assertEquals(2, index1.getStatistics().getNumberOfKeys());
      assertEquals(2, index1.getStatistics().getNumberOfValues());
      assertEquals(2, index1.getStatistics().getNumUpdates());
      assertEquals(2, index0.getStatistics().getNumberOfKeys());
      assertEquals(2, index0.getStatistics().getNumberOfValues());
      assertEquals(4, index0.getStatistics().getNumUpdates());

      aIregion.put("noQkey4", "noQval4");
      while (!upThread.isDone()) {
        pause(20);
      }
      waitForUpdates(aIindex0, 4);
      waitForUpdates(aIindex1, 2);
      waitForKeys(aIindex0, 2);
      // waitForKeys(aIindex1, 2);
      // assertIndexDetailsEquals(2, aIindex1.getStatistics().getNumberOfKeys());
      assertEquals(2, aIindex1.getStatistics().getNumberOfValues());
      assertEquals(2, aIindex1.getStatistics().getNumUpdates());
      assertEquals(2, aIindex0.getStatistics().getNumberOfKeys());
      assertEquals(2, aIindex0.getStatistics().getNumberOfValues());
      assertEquals(4, aIindex0.getStatistics().getNumUpdates());

      q = qs.newQuery(qstr + " where value < 'q'");
      res = (SelectResults) q.execute();
      assertEquals(2, index1.getStatistics().getTotalUses());
      assertEquals(0, res.size());

      aIq1 = qs.newQuery(aIqstr + " where value <'q'");
      res = (SelectResults) aIq1.execute();
      assertEquals(2, aIindex1.getStatistics().getTotalUses());
      assertEquals(0, res.size());

      q = qs.newQuery(qstr + " where value.length > 6");
      res = (SelectResults) q.execute();
      assertEquals(2, index0.getStatistics().getTotalUses());
      assertEquals(0, res.size());

      aIq1 = qs.newQuery(aIqstr + " where value.length > 6");
      res = (SelectResults) aIq1.execute();
      assertEquals(2, aIindex0.getStatistics().getTotalUses());
      assertEquals(0, res.size());

      this.txMgr.commit();
      assertEquals(3, index1.getStatistics().getNumberOfKeys());
      assertEquals(3, index1.getStatistics().getNumberOfValues()); // Shouldn't this be 4?
      assertEquals(5, index1.getStatistics().getNumUpdates());
      assertEquals(2, index0.getStatistics().getNumberOfKeys());
      assertEquals(3, index0.getStatistics().getNumberOfValues()); // Shouldn't this be 4?
      assertEquals(7, index0.getStatistics().getNumUpdates());

      while (!upThread.isDone()) {
        pause(20);
      }
      waitForUpdates(aIindex0, 7);
      waitForUpdates(aIindex1, 5);
      // waitForKeys(aIindex0, 4); // sometimes 3 sometimes 4
      // waitForKeys(aIindex1, 3);
      assertEquals(3, aIindex1.getStatistics().getNumberOfKeys());
      assertEquals(3, aIindex1.getStatistics().getNumberOfValues()); // Shouldn't this be 4?
      assertEquals(5, aIindex1.getStatistics().getNumUpdates());
      // assertIndexDetailsEquals(4, aIindex0.getStatistics().getNumberOfKeys());
      assertEquals(3, aIindex0.getStatistics().getNumberOfValues()); // Shouldn't this be 4?
      assertEquals(7, aIindex0.getStatistics().getNumUpdates());

      q = qs.newQuery(qstr + " where value <'q'");
      res = (SelectResults) q.execute();
      assertEquals(3, index1.getStatistics().getTotalUses());
      assertEquals(2, res.size());

      aIq1 = qs.newQuery(aIqstr + " where value < 'q'");
      res = (SelectResults) aIq1.execute();
      assertEquals(3, aIindex1.getStatistics().getTotalUses());
      assertEquals(2, res.size());

      q = qs.newQuery(qstr + " where value.length > 6");
      res = (SelectResults) q.execute();
      assertEquals(3, index0.getStatistics().getTotalUses());
      assertEquals(2, res.size());

      aIq1 = qs.newQuery(aIqstr + " where value.length > 6");
      res = (SelectResults) aIq1.execute();
      assertEquals(3, aIindex0.getStatistics().getTotalUses());
      assertEquals(2, res.size());
    } finally {
      IndexManager.TEST_RANGEINDEX_ONLY = false;
    }
  }

  /**
   * make sure that we do not expose BucketRegion on transactionListener events
   *
   */
  @Test
  public void testInternalRegionNotExposed() throws Exception {
    TransactionListenerForRegionTest tl = new TransactionListenerForRegionTest();
    CacheTransactionManager ctm = this.cache.getCacheTransactionManager();
    ctm.addListener(tl);
    CacheListenerForRegionTest cl = new CacheListenerForRegionTest();
    AttributesFactory af = new AttributesFactory();
    PartitionAttributes pa =
        new PartitionAttributesFactory().setRedundantCopies(0).setTotalNumBuckets(1).create();
    af.setPartitionAttributes(pa);
    af.addCacheListener(cl);
    Region pr = this.cache.createRegion("testTxEventForRegion", af.create());
    pr.put(2, "tw");
    pr.put(3, "three");
    pr.put(4, "four");
    ctm.begin();
    pr.put(1, "one");
    pr.put(2, "two");
    pr.invalidate(3);
    pr.destroy(4);
    ctm.commit();
    assertFalse(tl.exceptionOccurred);
    assertFalse(cl.exceptionOccurred);
  }



  /**
   * make sure that we throw an UnsupportedOperationInTransactionException
   *
   */
  @Test
  public void testPutAllSupported() throws Exception {
    TXManagerImpl ctm = this.cache.getTxManager();
    AttributesFactory af = new AttributesFactory();
    Region r = this.cache.createRegion("dRegion", af.create());
    PartitionAttributes pa =
        new PartitionAttributesFactory().setRedundantCopies(0).setTotalNumBuckets(1).create();
    af.setPartitionAttributes(pa);
    Region pr = this.cache.createRegion("prRegion", af.create());
    Map map = new HashMap();
    map.put("stuff", "junk");
    map.put("stuff2", "junk2");
    ctm.begin();
    pr.putAll(map);
    r.putAll(map);
    TXStateProxy tx = ctm.pauseTransaction();
    assertTrue(!pr.containsKey("stuff"));
    assertTrue(!r.containsKey("stuff"));
    ctm.unpauseTransaction(tx);
    ctm.commit();
    assertTrue(pr.containsKey("stuff"));
    assertTrue(r.containsKey("stuff"));
  }


  /**
   * make sure that we throw an UnsupportedOperationInTransactionException
   *
   */
  @Test
  public void testGetAllSupported() throws Exception {
    CacheTransactionManager ctm = this.cache.getCacheTransactionManager();
    AttributesFactory af = new AttributesFactory();
    Region r = this.cache.createRegion("dRegion", af.create());
    PartitionAttributes pa =
        new PartitionAttributesFactory().setRedundantCopies(0).setTotalNumBuckets(1).create();
    af.setPartitionAttributes(pa);
    Region pr = this.cache.createRegion("prRegion", af.create());
    List list = new ArrayList();
    list.add("stuff");
    list.add("stuff2");
    ctm.begin();
    pr.getAll(list);
    r.getAll(list);
    ctm.commit();
    // now we aren't in tx so these shouldn't throw
    pr.getAll(list);
    r.getAll(list);
  }



  /**
   * make sure that we throw an UnsupportedOperationInTransactionException
   *
   */
  @Test
  public void testDestroyRegionNotSupported() throws Exception {
    CacheTransactionManager ctm = this.cache.getCacheTransactionManager();
    AttributesFactory af = new AttributesFactory();
    Region r = this.cache.createRegion("dRegion", af.create());
    PartitionAttributes pa =
        new PartitionAttributesFactory().setRedundantCopies(0).setTotalNumBuckets(1).create();
    af.setPartitionAttributes(pa);
    Region pr = this.cache.createRegion("prRegion", af.create());
    List list = new ArrayList();
    list.add("stuff");
    list.add("stuff2");
    ctm.begin();
    try {
      pr.destroyRegion();
      fail("Should have thrown UnsupportedOperationInTransactionException during destroyRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }
    try {
      pr.localDestroyRegion();
      fail(
          "Should have thrown UnsupportedOperationInTransactionException during localDestroyRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }
    try {
      r.destroyRegion();
      fail("Should have thrown UnsupportedOperationInTransactionException during destroyRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }

    try {
      r.localDestroyRegion();
      fail(
          "Should have thrown UnsupportedOperationInTransactionException during localDestroyRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }
    assertTrue(!pr.isDestroyed());
    assertTrue(!r.isDestroyed());

    ctm.commit();
    // now we aren't in tx so these shouldn't throw
    pr.destroyRegion();
    r.destroyRegion();

  }

  /**
   * make sure that we throw an UnsupportedOperationInTransactionException
   *
   */
  @Test
  public void testInvalidateRegionNotSupported() throws Exception {
    CacheTransactionManager ctm = this.cache.getCacheTransactionManager();
    AttributesFactory af = new AttributesFactory();
    Region r = this.cache.createRegion("dRegion", af.create());
    PartitionAttributes pa =
        new PartitionAttributesFactory().setRedundantCopies(0).setTotalNumBuckets(1).create();
    af.setPartitionAttributes(pa);
    Region pr = this.cache.createRegion("prRegion", af.create());
    ctm.begin();
    try {
      pr.invalidateRegion();
      fail("Should have thrown UnsupportedOperationInTransactionException during invalidateRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }
    try {
      pr.localInvalidateRegion();
      fail(
          "Should have thrown UnsupportedOperationInTransactionException during localInvalidateRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }
    try {
      r.invalidateRegion();
      fail("Should have thrown UnsupportedOperationInTransactionException during invalidateRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }

    try {
      r.localInvalidateRegion();
      fail(
          "Should have thrown UnsupportedOperationInTransactionException during localInvalidateRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }
    ctm.commit();
    // now we aren't in tx so these shouldn't throw
    pr.invalidateRegion();
    r.invalidateRegion();

  }

  /**
   * make sure that we throw an UnsupportedOperationInTransactionException
   *
   */
  @Test
  public void testClearRegionNotSupported() throws Exception {
    CacheTransactionManager ctm = this.cache.getCacheTransactionManager();
    AttributesFactory af = new AttributesFactory();
    Region r = this.cache.createRegion("dRegion", af.create());
    PartitionAttributes pa =
        new PartitionAttributesFactory().setRedundantCopies(0).setTotalNumBuckets(1).create();
    af.setPartitionAttributes(pa);
    Region pr = this.cache.createRegion("prRegion", af.create());
    ctm.begin();
    try {
      pr.clear();
      fail("Should have thrown UnsupportedOperation during invalidateRegion");
    } catch (UnsupportedOperationException ee) {
      // expected
    }
    try {
      pr.localClear();
      fail("Should have thrown UnsupportedOperation during localInvalidateRegion");
    } catch (UnsupportedOperationException ee) {
      // expected
    }
    try {
      r.clear();
      fail("Should have thrown UnsupportedOperationInTransactionException during invalidateRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }

    try {
      r.localClear();
      fail(
          "Should have thrown UnsupportedOperationInTransactionException during localInvalidateRegion");
    } catch (UnsupportedOperationInTransactionException ee) {
      // expected
    }
    ctm.commit();
    // now we aren't in tx so these shouldn't throw
    pr.invalidateRegion();
    r.invalidateRegion();

  }

  @Test
  public void testBug51781() {
    AttributesFactory<Integer, String> af = new AttributesFactory<Integer, String>();
    af.setDataPolicy(DataPolicy.NORMAL);
    Region<Integer, String> r = this.cache.createRegion(getUniqueName(), af.create());
    CacheTransactionManager mgr = this.cache.getCacheTransactionManager();
    r.put(1, "value1");
    r.put(2, "value2");
    assertEquals(2, r.size());
    mgr.begin();
    r.put(3, "value3");
    r.destroy(3);
    mgr.commit();
    assertEquals(2, r.size());
  }

  private String getUniqueName() {
    return getClass().getSimpleName() + "_" + testName.getMethodName();
  }

  private static class TransactionListenerForRegionTest extends TransactionListenerAdapter {
    private boolean exceptionOccurred = false;

    @Override
    public void afterCommit(TransactionEvent event) {
      List<CacheEvent<?, ?>> events = event.getEvents();
      for (CacheEvent<?, ?> e : events) {
        if (!"/testTxEventForRegion".equals(e.getRegion().getFullPath())) {
          exceptionOccurred = true;
        }
      }
    }
  }

  private static class CacheListenerForRegionTest extends CacheListenerAdapter {
    private boolean exceptionOccurred = false;

    @Override
    public void afterCreate(EntryEvent event) {
      verifyRegion(event);
    }

    @Override
    public void afterUpdate(EntryEvent event) {
      verifyRegion(event);
    }

    private void verifyRegion(EntryEvent event) {
      if (!"/testTxEventForRegion".equals(event.getRegion().getFullPath())) {
        exceptionOccurred = true;
      }
    }
  }

  private void verifyEventProps(EntryEvent ev) {
    assertTrue(!ev.getOperation().isLocalLoad());
    assertTrue(!ev.getOperation().isNetLoad());
    assertTrue(!ev.getOperation().isLoad());
    assertTrue(!ev.getOperation().isNetSearch());
  }

  private enum OperationType {
    REPLACE, REMOVE
  }

  @Test
  public void removeShouldNotCleanupRepeatableReadTXEntriesIfEntryNotFound() {
    repeatableReadTXEntriesShouldNotBeCleanedUpIfEntryNotFound(OperationType.REMOVE);
  }

  @Test
  public void replaceShouldNotCleanupRepeatableReadTXEntriesIfEntryNotFound() {
    repeatableReadTXEntriesShouldNotBeCleanedUpIfEntryNotFound(OperationType.REPLACE);
  }

  private void repeatableReadTXEntriesShouldNotBeCleanedUpIfEntryNotFound(OperationType type) {
    RegionFactory regionFactory = cache.createRegionFactory(RegionShortcut.REPLICATE);
    Region<Integer, String> region = regionFactory.create(getUniqueName());
    region.put(1, "value1");
    region.put(2, "value2");
    txMgr.begin();
    region.put(1, "newValue1");
    TransactionId transaction1 = txMgr.suspend();

    txMgr.begin();
    region.get(1); // a repeatable read operation
    switch (type) {
      case REMOVE:
        assertThat(region.remove(2, "nonExistingValue")).isFalse();
        break;
      case REPLACE:
        assertThat(region.replace(2, "newValue", "nonExistingValue")).isFalse();
        break;
      default:
        throw new RuntimeException("Unknown operation");
    };
    TransactionId transaction2 = txMgr.suspend();

    txMgr.resume(transaction1);
    txMgr.commit();

    txMgr.resume(transaction2);
    region.put(1, "anotherValue");
    assertThatThrownBy(() -> txMgr.commit()).isInstanceOf(CommitConflictException.class);
  }

}
