public void testTxAlgebra()

in geode-core/src/integrationTest/java/org/apache/geode/TXJUnitTest.java [986:2743]


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

    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 = region.getAttributesMutator();
    CountingCacheListener cntListener = new CountingCacheListener() {
      volatile int aCreateCalls, aUpdateCalls, aInvalidateCalls, aDestroyCalls, aLocalDestroyCalls;

      @Override
      public void close() {}

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

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

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

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

      @Override
      public void afterDestroy(EntryEvent e) {
        if (e.getOperation().isDistributed()) {
          ++aDestroyCalls;
        } else {
          ++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 aCreateCalls;
      }

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

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

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

      @Override
      public void close() {}

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

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

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

      @Override
      public void beforeDestroy(EntryEvent e) {
        ++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 bCreateCalls;
      }

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

      @Override
      public int getBeforeDestroyCalls(boolean fetchLocal) {
        return fetchLocal ? bLocalDestroyCalls : 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();
    txMgr.begin();
    myTxId = txMgr.getTransactionId();
    reg1.create("key1", "value1");
    callbackVal.assertCreateWriterCnt(1);
    try {
      reg1.create("key1", "value2");
      fail("expected EntryExistsException");
    } catch (EntryExistsException ignored) {
    }
    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);
    txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.reAssert();
    assertEquals("value2", reg1.getEntry("key1").getValue());
    assertEquals(1, te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getPutEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(te.getEvents()).size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(te.getEvents());
      assertEquals(myTxId, 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();
    txMgr.begin();
    myTxId = 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);
    txMgr.commit();
    callbackVal.assertCreateListenerCnt(1);
    callbackVal.reAssert();
    assertTrue(reg1.containsKey("key1"));
    assertTrue(!reg1.containsValueForKey("key1"));
    assertEquals(1, te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getPutEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(te.getEvents()).size());
    {
      List<EntryEvent<?, ?>> events =
          TxEventTestUtil.getCreateEvents(te.getEvents());
      assertEquals(myTxId, 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();
    txMgr.begin();
    reg1.create("key1", "value0");
    callbackVal.assertCreateWriterCnt(1);
    reg1.destroy("key1");
    callbackVal.assertDestroyWriterCnt(1);
    assertTrue(!reg1.containsKey("key1"));
    callbackVal.assertDestroyListenerCnt(0);
    txMgr.commit();
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, te.getEvents().size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getPutEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(te.getEvents()).size());

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

    // Check C + LI + DD -> NOOP
    callbackVal.reset();
    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"));
    txMgr.commit();
    callbackVal.assertDestroyListenerCnt(0);
    callbackVal.assertCreateListenerCnt(0);
    callbackVal.reAssert();
    assertTrue(!reg1.containsKey("key1"));
    assertEquals(0, TxEventTestUtil.getPutEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getInvalidateEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getCreateEvents(te.getEvents()).size());
    assertEquals(0, TxEventTestUtil.getDestroyEvents(te.getEvents()).size());
    assertEquals(0, te.getEvents().size());

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

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