/*
 * 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.util.StopWatch;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * 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);
  }

}
